Delayed Expansion and escapes
Moderator: DosItHelp
Delayed Expansion and escapes
Is there some kind of formula to figure out how many of them you'll need instead of guessing it & trying all possibilities to display a ! ^! ^^^! ^^^^^^^! ^^^^^^^^^^^^! ^^^^^^^^^^^^^^^^^!
Re: Delayed Expansion and escapes
As long as you know how many times the character needs to be escaped it's not difficult. The total number of characters is simply a power of 2.
0 escapes = 2^0 = 1 = !
1 escape = 2^1 = 2 = ^!
2 escapes = 2^2 = 4 = ^^^!
3 escapes = 2^3 = 8 = ^^^^^^^!
etc.
One problem is it is not always obvious how many times you need to escape!
results:
Dave Benham
0 escapes = 2^0 = 1 = !
1 escape = 2^1 = 2 = ^!
2 escapes = 2^2 = 4 = ^^^!
3 escapes = 2^3 = 8 = ^^^^^^^!
etc.
One problem is it is not always obvious how many times you need to escape!
Code: Select all
@echo off
setlocal enableDelayedExpansion
prompt $g
echo on
rem Unquoted uses 2 escapes on each pass, so 2^6=64 chars initially!
set v1=^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
set v2=%v1%
set v3=%v2%
set v
rem Quoted uses only 1 escape per pass, so 2^3=8 chars initially.
set "v1=^^^^^^^!"
set "v2=%v1%"
set "v3=%v2%"
set v
results:
Code: Select all
>rem Unquoted uses 2 escapes on each pass, so 2^6=64 chars initially!
>set v1=^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
>set v2=^^^^^^^!
>set v3=^!
>set v
v1=^^^^^^^^^^^^^^^!
v2=^^^!
v3=!
>rem Quoted uses only 1 escape per pass, so 2^3=8 chars initially.
>set "v1=^^^^^^^!"
>set "v2=^^^!"
>set "v3=^!"
>set v
v1=^^^!
v2=^!
v3=!
Dave Benham
Re: Delayed Expansion and escapes
Code: Select all
>rem Unquoted uses 2 escapes on each pass, so 2^6=64 chars initially!
>set v1=^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
>set v2=!v1!
>set v3=!v2!
>set v
v1=^^^^^^^^^^^^^^^!
v2=^^^^^^^^^^^^^^^!
v3=^^^^^^^^^^^^^^^!
>rem Quoted uses only 1 escape per pass, so 2^3=8 chars initially.
>set "v1=^^^^^^^!"
>set "v2=!v1!"
>set "v3=!v2!"
>set v
v1=^^^!
v2=^^^!
v3=^^^!
endoftest
Code: Select all
rem Unquoted uses 2 escapes on each pass, so 2^2=4 chars initially!
set v1=^^^!
set v2=!v1!
set v3=!v2!
set v
rem Quoted uses only 1 escape per pass, so 2^1=2 chars initially.
set "v1=^!"
set "v2=!v1!"
set "v3=!v2!"
set v
set "v2=!v1!" and set "v3=!v2!" don't seem to be considered a pass
Code: Select all
>rem Unquoted uses 2 escapes on each pass, so 2^2=4 chars initially!
>set v1=^!
>set v2=!v1!
>set v3=!v2!
>set v
v1=!
v2=!
v3=!
>rem Quoted uses only 1 escape per pass, so 2^1=2 chars initially.
>set "v1=^!"
>set "v2=!v1!"
>set "v3=!v2!"
>set v
v1=!
v2=!
v3=!
endoftest
So that brings me to this conclusion :
Code: Select all
::--------------------------------------------------------------------------------------------------------------------------
@echo off &prompt $g &echo on
setlocal enableDelayedExpansion
rem Escapes are used when a variable is set, echoed, passed to a variable &passed as a parameter.
rem ::(
rem ::QuickList
rem ::(
rem 0 escapes = 2^0 = 1 = !
rem 1 escape = 2^1 = 2 = ^!
rem 2 escapes = 2^2 = 4 = ^^^!
rem 3 escapes = 2^3 = 8 = ^^^^^^^!
rem 4 escapes = 2^4 = 16 = ^^^^^^^^^^^^^^^!
rem 5 escapes = 2^5 = 32 = ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
rem 6 escapes = 2^6 = 64 = ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
rem ::)
rem
rem set is a pass when using set=%variable%
rem Unquoted uses 2 escapes on each pass, so 2^6=64 chars initially!
set v1=^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
set v2=%v1%
set v3=%v2%
set v
rem set is a pass when using set=%variable%
rem Quoted uses only 1 escape per pass, so 2^3=8 chars initially.
set "v1=^^^^^^^!"
set "v2=%v1%"
set "v3=%v2%"
set v
rem set is only one a pass when using set=!variable!
rem Unquoted uses 2 escapes per pass, so 2^2=4 chars initially!
set v1=^^^!
set v2=!v1!
set v3=!v2!
set v
rem set is only one pass when using set=!variable!
rem Quoted uses 1 escapes per pass, so 2^1=2 chars initially.
set "v1=^!"
set "v2=!v1!"
set "v3=!v2!"
set v
@echo off &echo.endoftest &pause &exit
::--------------------------------------------------------------------------------------------------------------------------
Re: Delayed Expansion and escapes
Hi Ed,
there are exactly three different caret phases.
The special character phase:
The caret escapes the next character and is removed, but works only outside of quotes.
Exclamation marks are not important at this phase.
The delayed phase
The caret escapes the next character, only important for exclamation marks, doesn't care about quotes.
AND this phase is only executed if there is at least on exclamation mark in the line.
The call phase:
All carets are doubled, don't care about quotes. This seems to be false, as you normally didn't see double quotes, but this is only, because they are normally removed by the next special character phase.
Samples
Output
jeb
there are exactly three different caret phases.
The special character phase:
The caret escapes the next character and is removed, but works only outside of quotes.
Exclamation marks are not important at this phase.
The delayed phase
The caret escapes the next character, only important for exclamation marks, doesn't care about quotes.
AND this phase is only executed if there is at least on exclamation mark in the line.
The call phase:
All carets are doubled, don't care about quotes. This seems to be false, as you normally didn't see double quotes, but this is only, because they are normally removed by the next special character phase.
Samples
Code: Select all
setlocal enableDelayedExpansion
echo without exclam ^^^^ "^^^^"
echo with exclam ^^^^ "^^^^" !
set "^=one"
set "^^=two"
set "caret=^"
call echo %%!caret!%% caret
call call call call echo ^^^^ "^^^^"
Output
Code: Select all
without exclam ^^ "^^^^"
with exclam ^ "^^"
two caret
^^ "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
jeb