【发布时间】:2012-01-19 13:53:42
【问题描述】:
假设我有一个字符串,例如 foo:bar:baz,是否可以循环遍历该字符串?看起来您可以标记文件的行,但以下内容只会回显“foo”一次。
for /f "tokens=1,2* delims=:" %%x in ("%%j") do echo %%x
【问题讨论】:
标签: batch-file
假设我有一个字符串,例如 foo:bar:baz,是否可以循环遍历该字符串?看起来您可以标记文件的行,但以下内容只会回显“foo”一次。
for /f "tokens=1,2* delims=:" %%x in ("%%j") do echo %%x
【问题讨论】:
标签: batch-file
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
【讨论】:
Aacini 在我的第一个解决方案中击败了我。可以通过添加引号来改进它,以便字符串可以包含空格和特殊字符并且仍然给出正确的结果。
set "str=foo bar:biz bang:this & that"
for %%S in ("%str::=" "%") do echo %%~S
解决方案有局限性:
第二种解决方案的语法很奇怪,但概念相当简单。带有“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
)
我相信这种技术几乎可以处理你扔给它的任何东西。
jeb 是第一个向我展示如何在批处理中使用换行符,尤其是如何使用这种技术的人。它甚至可能已经在 SO 上的其他地方发布。
【讨论】:
^"?你为什么不逃避第二个?
" 会使^ 按字面意思保留...相当书呆子,不是吗? ;-)
正如预期的那样,它将其标记为%%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
【讨论】:
这会将字符串解析为可在循环外访问的变量 (;
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!
【讨论】: