下面的代码片段会删除所有额外的垃圾,直到错误生成代码,
)“”此时出人意料。
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
Set "regex="(Test_Health=(?!100))""
echo Regex is: %regex%
FOR /L %%I IN (1,1,5) DO (
Set "to_call=call crv.exe "%%I" %regex%"
echo About to call: !to_call!
)
基本上,在真实的脚本中,我正在尝试调用一个命令行工具,该工具采用一个带有可能特殊字符的复杂字符串,以及一个正则表达式。
我想出了一个解决方法,即在^
的最后一句话之前添加一个插入符号%%I
):
Set "to_call=call crv.exe "%%I^" %regex%"
但这感觉就像是脏黑客。我做错了什么,如果没有肮脏的黑客行为,我该怎么做才能获得理想的行为?
答案 0 :(得分:2)
无需黑客即可解决问题:
确保!
字符。在您的regex
变量值中,系统会将其识别为文字:
Set "regex=(Test_Health=(?^!100))"
由于setlocal enabledelayedexpansion
,文字 !
字符。内部"..."
必须转发为^!
。
请注意,<name>=<value>
令牌是双引号整体,以防止对该值进行额外解释。
regex
循环体内的参考变量for
延迟:
使用!regex!
代替%regex%
。
为了使得到的命令行更加健壮 - 即使在这种特定情况下不需要 - 确保regex
的值用双引号括起来(注意%%I
- as仅仅是一个数字 - 不需要引用):
Set "to_call=call crv.exe %%I "!regex!""
把它们放在一起:
@echo off
setlocal enabledelayedexpansion enableextensions
Set "regex=(Test_Health=(?^!100))"
echo Regex is: %regex%
FOR /L %%I IN (1,1,5) DO (
Set "to_call=call crv.exe %%I "!regex!""
echo About to call: !to_call!
)
的产率:
Regex is: (Test_Health=(?100))
call crv.exe 1 "(Test_Health=(?!100))"
call crv.exe 2 "(Test_Health=(?!100))"
call crv.exe 3 "(Test_Health=(?!100))"
call crv.exe 4 "(Test_Health=(?!100))"
call crv.exe 5 "(Test_Health=(?!100))"
至于你做错了什么:
%<name>%
- 样式变量引用 - 除了循环变量(在本例中为%%I
) - 在循环体((...)
)内扩展循环甚至是解析,因此这些变量引用的值可以打破循环。
以下是演示此问题的最小示例:
@echo off
Set "regex=))"
FOR %%I IN ("dummy") DO (
rem !! breaks, because the up-front %regex% expansion causes a syntax error.
echo %regex%
)
延迟扩展 - 将变量名称括在!...!
中,假设setlocal enabledelayedexpansion
生效 - 绕过此问题:
@echo off
setlocal enabledelayedexpansion
Set "regex=))"
FOR %%I IN ("dummy") DO (
rem OK - outputs "))"
echo !regex!
)
答案 1 :(得分:2)
@ECHO OFF
SETLOCAL
Set "regex="(Test_Health=(?^^^^!100^^)^^)""
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
echo Regex is: %regex%
FOR /L %%I IN (1,1,5) DO (
Set "to_call=call crv.exe "%%I" %regex%"
echo About to call: !to_call!
)
GOTO :EOF
排序取决于您的“期望行为”。不幸的是,你没有指定。
理解cmd
如何工作 - 通过替换,使用转义字符及其发生的顺序。
报告正则表达式的echo
不会产生正确的结果。然而,在for
内,每对插入符被解释为单个插入符号,因此所需的转义符是预期输出所需的,大概是call crv.exe "5" "(Test_Health=(?!100))"
之类......等等。