批处理字符串索引和延迟扩展

时间:2016-05-29 09:30:20

标签: batch-file delayedvariableexpansion

我已将有问题的代码删除到有问题的行。为什么第一个回声有效,第二回声不起作用?

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 

EDITED: 我一直在努力,这条线有效:

call set line=%%blocks:~0,!w2!%%

现在的问题是:有人可以向我解释为什么我必须使用电话?

2 个答案:

答案 0 :(得分:1)

您应该直接使用r变量和扩展百分比,只要该值不会在循环内发生变化。

set line=!blocks:~0,%r%!

或者为其他变量使用辅助循环。

 for /F "tokens=*" %%H in ("!w2!") do (
      set line=!blocks:~0,%%H!
   )

答案 1 :(得分:1)

扩展变量的可能方法!延迟扩展!在this post中描述了可能在代码块内部发生变化的子串位置或长度的其他变量:

要在FOR / IF内部索引更改时获取子字符串的值,请将子字符串括在双百分比符号中,并在命令前加上call。例如:

call set line=%%blocks:~0,!w2!%%

此方法充分利用了call命令允许重新扩展以双百分号括起来的变量的事实,如this question的第二个答案中所述:

BatchLineParser:

1)阶段:扩展%var% ...

6)阶段:如果命令是CALL,则再次从阶段1开始。

实现上一个过程的另一种方法是使用额外的FOR命令通过等效的可替换参数更改索引的延迟扩展,然后对子字符串使用延迟扩展。此方法比以前的CALL运行得更快:

for %%w in (!w2!) do set line=!blocks:~0,%%w!