批量字符串索引和延迟扩展
batch string indexing and delayed expansion
我已将有问题的代码剥离到有问题的行。为什么第一个回声有效,第二个回声无效?
setlocal enabledelayedexpansion
set /a r=19
set blocks=MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
for /L %%a in (-%r%,1,%r%) do (
set /a w2=r
:: This works
set line=!blocks:~0,%r%!
echo( !line!
::This does'nt work
set line=!blocks:~0,!w2!!
echo( !line!
)
exit /b
已编辑:
我一直在尝试,这一行有效:
call set line=%%blocks:~0,!w2!%%
现在的问题是:有人可以向我解释为什么我必须使用 call 吗?
您应该直接使用带有百分比扩展的 r
变量,只要该值在循环内不发生变化即可。
set line=!blocks:~0,%r%!
或者对其他变量使用辅助循环。
for /F "tokens=*" %%H in ("!w2!") do (
set line=!blocks:~0,%%H!
)
使用!delayed expansion扩展变量的可能方法!在 this post:
中描述了使用其他变量作为子串位置或长度,这些变量可能在代码块内发生变化
要在索引在 FOR/IF 内发生变化时获取子字符串的值,请将子字符串用双百分号括起来,并在命令前加上 call。例如:
call set line=%%blocks:~0,!w2!%%
此方法很好地利用了 call
命令允许重新扩展包含在双百分号中的变量这一事实,如 this question:[=16 的第二个答案中所述=]
BatchLineParser:
1) 阶段:扩展 %var%
...
6)阶段:如果命令是CALL,则再次从阶段1开始。
另一种实现上述过程的方法是使用一个额外的FOR命令,通过一个等效的可替换参数来改变索引的延迟扩展,然后对子串使用延迟扩展。这个方法比之前的 CALL 运行得更快:
for %%w in (!w2!) do set line=!blocks:~0,%%w!
我已将有问题的代码剥离到有问题的行。为什么第一个回声有效,第二个回声无效?
setlocal enabledelayedexpansion
set /a r=19
set blocks=MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
for /L %%a in (-%r%,1,%r%) do (
set /a w2=r
:: This works
set line=!blocks:~0,%r%!
echo( !line!
::This does'nt work
set line=!blocks:~0,!w2!!
echo( !line!
)
exit /b
已编辑: 我一直在尝试,这一行有效:
call set line=%%blocks:~0,!w2!%%
现在的问题是:有人可以向我解释为什么我必须使用 call 吗?
您应该直接使用带有百分比扩展的 r
变量,只要该值在循环内不发生变化即可。
set line=!blocks:~0,%r%!
或者对其他变量使用辅助循环。
for /F "tokens=*" %%H in ("!w2!") do (
set line=!blocks:~0,%%H!
)
使用!delayed expansion扩展变量的可能方法!在 this post:
中描述了使用其他变量作为子串位置或长度,这些变量可能在代码块内发生变化要在索引在 FOR/IF 内发生变化时获取子字符串的值,请将子字符串用双百分号括起来,并在命令前加上 call。例如:
call set line=%%blocks:~0,!w2!%%
此方法很好地利用了 call
命令允许重新扩展包含在双百分号中的变量这一事实,如 this question:[=16 的第二个答案中所述=]
BatchLineParser:
1) 阶段:扩展 %var%
...
6)阶段:如果命令是CALL,则再次从阶段1开始。
另一种实现上述过程的方法是使用一个额外的FOR命令,通过一个等效的可替换参数来改变索引的延迟扩展,然后对子串使用延迟扩展。这个方法比之前的 CALL 运行得更快:
for %%w in (!w2!) do set line=!blocks:~0,%%w!