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

时间:2011-12-13 17:29:05

标签: batch-file

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

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

4 个答案:

答案 0 :(得分:18)

set string=foo:bar:baz
for %%x in (%string::= %) do echo %%x

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

set string=foo bar,baz;one=two
for %%x in (%string%) do echo %%x

答案 1 :(得分:9)

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

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

解决方案有局限性:

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

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

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

最后,我们需要使用延迟扩展,但如果我们不首先在循环内禁用延迟扩展,{%{1}}将在%% S扩展期间被破坏。

!

我相信这种技术几乎可以处理你扔的任何东西。

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

答案 2 :(得分:2)

它按预期执行,将其标记为%%x %%y %%z。因此,您可能不会只处理%%x,而是......

for /f "tokens=* delims=:" %%x in ("foo:bar:baz") do (
  echo %%x
  echo %%y
  echo %%z
)

或者如果你事先并不知道你有多少物品,你可以......

@echo off
set string=foo:bar:baz
:again
for /f "tokens=1* delims=:" %%x in ("%string%") do (
   echo %%x 
   set string=%%y
)
if not .%string%==. goto again
echo done

答案 3 :(得分:1)

这会将字符串解析为循环外部可访问的变量(;

setlocal enabledelayedexpansion

set your_string="whatever:you:want"

for /f "tokens=1,2,3 delims=:" %%a in ('echo !your_string!') do (
    set first_sub_string=%%a
    set second_sub_string=%%b
    set third_sub_string=%%c
)

echo Congrats.  !your_string! was parsed as !first_sub_string!, !second_sub_string!, !third_sub_string!