【发布时间】:2016-07-15 11:52:50
【问题描述】:
假设在启用delayed expansion 时,想要使用substring replacement 语法用感叹号替换某些子字符串,他们必须使用立即(正常)扩展,因为解析器无法区分!s 用于扩展和文字那些。
但是,为什么必须在替换字符串中转义感叹号?以及为什么搜索字符串中的感叹号转义没有必要甚至破坏性?
以下脚本将字符串中的!s 替换为`,然后以相反的顺序替换,所以我希望结果等于初始字符串(当然,它本身不能包含任何反引号):
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem This is the test string:
set "STRING=string!with!exclamation!marks!"
set "DELOFF=%STRING%"
set "DELOFF=%DELOFF:!=`%"
set "DELOFF=%DELOFF:`=!%"
setlocal EnableDelayedExpansion
set "DELEXP=!STRING!"
set "DELEXP=%DELEXP:!=`%"
set "DELEXP=%DELEXP:`=!%"
echo(original string: !STRING!
echo(normal expansion: !DELOFF!
echo(delayed expansion: !DELEXP!
endlocal
endlocal
exit /B
这个结果肯定不是我想要的,最后一个字符串不一样:
original string: string!with!exclamation!marks! normal expansion: string!with!exclamation!marks! delayed expansion: stringexclamation
只要走线...:
set "DELEXP=%DELEXP:`=!%"
....并在那里将! 替换为^!,因此在替换字符串中转义了感叹号,结果正是我所期望的:
original string: string!with!exclamation!marks! normal expansion: string!with!exclamation!marks! delayed expansion: string!with!exclamation!marks!
当我尝试其他转义组合时(在替换和搜索字符串中转义感叹号,或仅在后者中转义),结果再次是上述不需要的。
我浏览了How does the Windows Command Interpreter (CMD.EXE) parse scripts? 的帖子,但我找不到对这种行为的解释,因为我知道正常(或立即,百分比)扩展是在延迟扩展发生之前很久就完成的,甚至可以识别任何感叹号。插入符号的识别和转义似乎也在之后发生。此外,字符串周围甚至还有引号,通常会在解析器中隐藏插入符号。
【问题讨论】:
标签: batch-file replace cmd escaping delayedvariableexpansion