13

为什么字符串操作在 if 语句中内联工作而不使用延迟扩展变量 - 但否则会失败。例如:

set test=testString
if %test:~0,4%==test echo Success

这工作正常;归来Success。但是,如果我执行以下操作:

setLocal enableDelayedExpansion
set test=testString
if !test:~0,4!==test echo Success

我收到错误 -4!==test was unexpected at this time.

显然,您可以通过执行类似set comp=!test:~0,4!then 的操作来解决此问题,只需!comp!在 if 语句中使用变量即可。

4

2 回答 2

10

npocmaka 正确诊断了 IF 命令有自己的特殊解析阶段的问题,并且变量扩展中的标记分隔符导致了问题。

替换也会导致一个问题:

:: This fails
if !test:String=!==test echo Success

正常扩展之所以起作用,是因为它发生在 IF 解析之前,而延迟扩展发生IF 解析之后。

使用引号的另一种方法是转义问题字符。

:: Both of these work
if !test:~0^,4!==test echo Success
if !test:String^=!==test echo Success
于 2013-12-03T03:22:56.233 回答
10

,;=<tab>并且<space>是 cmd.exe 的分隔符,并且在许多情况下,如果它们不在引号中并且像空格一样被忽略。可能在这种情况下,被视为第一个操作数的结尾,并且IF惊讶于没有有效的比较运算符,例如 this将打印yep

if a   ;==;,,=a echo yep

(但如果操作数的第一部分有等号,则不起作用)

但这不会:

if "a ;" == ";,,=a" echo yep

因此,要在使用逗号时做出有效的IF表达,您需要引号。这将起作用

setLocal enableDelayedExpansion
set test=testString
if "!test:~0,4!" == "test" echo Success

没有延迟的扩展替换立即进行,这将在没有引号的情况下工作:

set test=testString
setlocal disableDelayedExpansion
if %test:~0,4% == test echo Succes
endlocal

出于同样的原因,这将被视为错误的语法表达式(参见 jeb 的评论):

set "test="
setlocal disableDelayedExpansion
if %test% == test echo Succes
endlocal

可能不是完整的答案,但应该很接近。因为两者都echo !test:~0,4!可以echo %test:~0,4%在没有引号的情况下工作,这仍然是为什么完全IF失败的问题 -可能是因为IF命令使用它自己的解析器

作为结论 - 当您将字符串与以下内容进行比较时,使用引号总是很好的IF

  1. 带有延迟扩展的逗号和分号会造成麻烦。
  2. 没有延迟扩展未定义的变量会造成麻烦。
于 2013-12-03T00:10:46.747 回答