Why does string-manipulation work inline in an if statement without using delayed expansion variables - but fails otherwise. For example:
set test=testString
if %test:~0,4%==test echo Success
This works correctly; returning Success
. However if I do the following:
setLocal enableDelayedExpansion
set test=testString
if !test:~0,4!==test echo Success
I receive the error - 4!==test was unexpected at this time.
Obviously you can get around this by doing something like set comp=!test:~0,4!
then just using the !comp!
variable in the if statement.
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
,;=<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
:
- with delayed expansion commas and semicolons will cause troubles.
- without delayed expansion undefined variables will cause troubles.