如何在字符串中循环标记?

Joe*_*ano 15 batch-file

假设我有一个字符串,例如foo:bar:baz,是否可以遍历此字符串?它看起来像你可以标记文件的行,但以下只会回显'foo'一次.

for /f "tokens=1,2* delims=:" %%x in ("%%j") do echo %%x

Aac*_*ini 19

set string=foo:bar:baz
for %%x in (%string::= %) do echo %%x
Run Code Online (Sandbox Code Playgroud)

FOR值分隔符可以是空格,逗号,分号和等号.如果元素用任何这些字符分隔,您可以直接处理字符串.如果没有,只需更改其中一个字符的分隔符(如上所述).

set string=foo bar,baz;one=two
for %%x in (%string%) do echo %%x
Run Code Online (Sandbox Code Playgroud)


dbe*_*ham 9

Aacini打败了我的第一个解决方案.可以通过添加引号来改进它,以便字符串可以包含空格和特殊字符,并仍然给出正确的结果.

set "str=foo bar:biz bang:this & that"
for %%S in ("%str::=" "%") do echo %%~S
Run Code Online (Sandbox Code Playgroud)

解决方案有局限性:

  • 不*或?可以出现在字符串中
  • 如果字符串已经包含引号("),则会出现问题,特别是如果还有特殊字符

第二种解决方案具有奇怪的语法,但概念相当直接.带有"string"的FOR/F将在换行字符上中断 - 每行将作为自己的字符串处理.诀窍是:用换行符替换分隔符.请注意,下面解决方案中的空白行是棘手更换的关键部分.此外,以下行必须从!终止延迟变量扩展开始.不应该有任何领先的空间.

另一件需要担心的是令人讨厌的FOR/F"EOL"选项.我们不希望跳过任何以EOL字符开头的值,;默认情况下.由于我们已经删除了字符串分隔符:,因此我们可以安全地将其用作EOL.

最后,我们需要使用延迟扩展,但!如果我们不首先在循环内禁用延迟扩展,则会在%% S扩展期间损坏.

set "str=foo bar:biz bang:this & that "^& the other thing!":;How does this work?"
setlocal enableDelayedExpansion
set ^"str=!str::=^

!"
for /f "eol=: delims=" %%S in ("!str!") do (
  if "!!"=="" endlocal
  echo %%S
)
Run Code Online (Sandbox Code Playgroud)

我相信这种技术几乎可以处理你抛出的任何东西.

jeb是第一个向我展示如何在批处理中使用换行符,特别是如何使用这种技术.它甚至可能已经在SO上的其他地方发布了.