【问题标题】:Why can I not get a substring of a delayed expansion variable in an if statement?为什么我不能在 if 语句中获得延迟扩展变量的子字符串?
【发布时间】:2013-12-02 22:40:00
【问题描述】:

为什么字符串操作在 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! 之类的操作来解决此问题,然后只需在 if 语句中使用 !comp! 变量即可。

【问题讨论】:

  • if "!test:~0,4!" equ "test" echo Success - 以这种方式工作,但这当然不是答案......

标签: batch-file if-statement cmd delayedvariableexpansion


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    ,;=<tab> 和 <space> 是 cmd.exe 的分隔符,在许多情况下,如果它们不在引号中并充当空格,则它们会被忽略。可能在这种情况下,, 被视为第一个操作数的结尾IF 很惊讶没有有效的比较运算符,例如这将打印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
    

    For the same reason this will be taken as a wrong syntax expression(见 jeb 的评论):

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

    可能不是完整的答案,但应该很接近。因为echo !test:~0,4! 和echo %test:~0,4% 都可以在没有引号的情况下工作,所以为什么IF 会失败 - may because IF command uses its own parser

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

    1. 带有延迟扩展的逗号和分号会引起麻烦。
    2. 不延迟扩展未定义的变量会引起麻烦。

    【讨论】:

    • 为什么%test:~0,4% 不一样?
    • 好答案 - 我认为你的结束点是正确的。虽然,正如你所说,它并没有完全回答这个问题。我会在一段时间内将此答案标记为正确 - 如果我没有得到更简洁的答案。非常感谢。
    • 关键是delayedexpansion 就是这样——延迟到执行时间。在 PARSE 时, %var...% 被解析和替换,但是 !var...!不是 - 它将在 RUN 时被替换并被解释为一个简单的字符串。解析器因此看到 string*[separator]*string*==*string 但期待 string*[operator]*string。解析器看到的第二个字符串与其有效运算符列表不匹配,因此解析器调用该命令无效。
    猜你喜欢
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多