Why can I not get a substring of a delayed expansion variable in an if statement?

前端 未结 2 384
太阳男子
太阳男子 2021-01-02 00:30

Why does string-manipulation work inline in an if statement without using delayed expansion variables - but fails otherwise. For example:

set test=testString         


        
相关标签:
2条回答
  • 2021-01-02 00:43

    ,;=<tab> and <space> are delimiters for cmd.exe and in many cases are ignored if they are not in quotes and act like empty space.Probably in this case , is taken as the end of the first operand and IF is surprised that there is not valid comparison operator e.g. this will print yep :

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

    (but will not work if there's a equal sign in the first part of the operands)

    But this will not:

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

    so to make a valid IF expression when you use comma you need quotes.And this will work

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

    Without delayed expansion substitution is made immediately and this will work without quotes:

    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 (see jeb's comment):

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

    May be is not the complete answer , but should be close.As both echo !test:~0,4! and echo %test:~0,4% will work without quotes stays the question why exactly IF fails - may because IF command uses its own parser

    As a conclusion - it's always good to use quotes when you compare strings with IF :

    1. with delayed expansion commas and semicolons will cause troubles.
    2. without delayed expansion undefined variables will cause troubles.
    0 讨论(0)
  • 2021-01-02 01:03

    npocmaka correctly diagnosed the problem that the IF command gets its own special parsing phase, and token delimiters within the variable expansion are causing problems.

    Substitution also causes a problem:

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

    The reason why normal expansion works is because that occurs before the IF parsing, but delayed expansion occurs after IF parsing.

    An alternative to using quotes is to escape the problem characters.

    :: Both of these work
    if !test:~0^,4!==test echo Success
    if !test:String^=!==test echo Success
    
    0 讨论(0)
提交回复
热议问题