【问题标题】:How to loop through tokens in a string?如何遍历字符串中的标记?
【发布时间】:2012-01-19 13:53:42
【问题描述】:

假设我有一个字符串,例如 foo:bar:baz,是否可以循环遍历该字符串?看起来您可以标记文件的行,但以下内容只会回显“foo”一次。

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

【问题讨论】:

    标签: batch-file


    【解决方案1】:
    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
    

    【讨论】:

      【解决方案2】:

      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 上的其他地方发布。

      【讨论】:

      • 你能告诉我你为什么在字符串替换时转义第一个引号,如^"?你为什么不逃避第二个?
      • 啊该死的,愚蠢的我!我知道了:未转义的" 会使^ 按字面意思保留...相当书呆子,不是吗? ;-)
      【解决方案3】:

      正如预期的那样,它将其标记为%%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
      

      【讨论】:

      【解决方案4】:

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

      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!
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-19
        • 1970-01-01
        • 1970-01-01
        • 2010-09-18
        相关资源
        最近更新 更多