# Loop, Parse (解析字符串)

从一个字符串中获取子字符串(片段), 每次一个.

    Loop, Parse, InputVar , Delimiters, OmitChars

## 参数

Parse

  此参数必须为单词 PARSE, 且与其他类型的循环不同, 它不能为包含单词 PARSE 的变量引用.

InputVar

  需要被分解的变量的名称. 不要把名称括在百分号中, 除非您希望使用变量的 内容 作为被解析的变量名.

  [v1.1.21+]: 此参数可以是 `% 表达式`, 但是 "% "(百分号空格前缀) 必须使用.

Delimiters(分隔符)

  如果此参数为空或省略, 那么将把 InputVar 中的每个字符解析为单独的子字符串.

  如果此参数为 CSV, 那么将把 InputVar 按逗号分隔值格式标准进行解析. 这个是 MS Excel 生成的 CSV 文件行的示例:

      "first field",SecondField,"the word ""special"" is quoted literally",,"last field, has literal comma"

  其他情况下, Delimiters 中可以包含一个或多个字符(区分大小写), 其中的每个都被用来确定 InputVar 中子字符串之间的边界.

  分隔符不会被视为子字符串自身的一部分. 此外, 在 InputVar 中如果一对分隔符之间没有任何字符, 那么相应的子字符串将为空.

  例如: ``,`(转义的逗号) 将根据逗号每次出现的位置分割字符串. 同样地, 使用 %A_Tab%%A_Space% 作为分隔符将在 InputVar 中每次遇到空格或 tab 时开始一个新的子字符串.

  要使用字符串而不是字符作为分隔符, 首先使用 StrReplace() 或 StringReplace 把这个字符串在所有出现的地方替换为文本中从未使用的单个字符, 例如这些特殊字符的其中一个: ¢¤¥¦§©ª«®µ¶. 参考这个例子, 其中使用字符串 <br> 作为分隔符:

      StringReplace, NewHTML, HTMLString, <br>, ￠, All
      Loop, parse, NewHTML, ￠ ; 使用 ￠ 解析字符串.
      {
      ...
      }

OmitChars(删除字符)

  可选的字符列表(区分大小写), 用来从每个子字符串的开始和结尾部分移除这些字符. 例如, 如果在 OmitChars 使用 %A_Space%%A_Tab%, 那么每个解析出来的子字符串中开始和结尾部分(但中间的不会) 的空格和 tab 会被移除.

  如果 Delimiters 为空, 那么 OmitChars 表示应该考虑移除哪些字符(它们将不会出现在循环中).

  与其他大多数命令的最后一个参数不同, 在 OmitChars 中的逗号必须进行转义(`,).

## 备注

当您想对包含在字符串中的片段逐个进行操作时, 字符串解析循环很有用. 解析循环比 StrSplit() 或 StringSplit 使用更少的内存(因为它创建了永久的数组或伪数组) 且在大多数情况下更容易使用.

内置变量 A_LoopField 存在于任何解析循环中. 它包含了 InputVar 中当前子字符串(片段) 的内容. 如果一个内层解析循环包含在一个外层解析循环中, 则最内层循环的片段将具有优先权.

尽管不存在内置变量 "A_LoopDelimiter", 不过在此页面最底部的例子演示了如何检测在分割每个片段时是由于遇到哪个分隔符.

InputVar 或其片段没有大小限制. 此外, 如果 InputVar 的内容在循环执行期间改变了, 循环将 "无视" 这些变化, 因为它正在操作的是原始内容的临时副本.

要在解析前按不同的顺序排列字段, 请使用 Sort 命令.

请参阅 Loop 了解关于区块, Break, Continue 和 A_Index 变量(其存在于各种类型的循环中) 的相关信息.

## 相关

StrSplit(), 文件读取循环, Loop, Break, Continue, 区块, Sort, FileSetAttrib, FileSetTime, StringSplit

## 示例

解析一个逗号分隔的字符串.

    Colors := "red,green,blue"
    Loop, parse, Colors, `,
    {
        MsgBox, Color number %A_Index% is %A_LoopField%.
    }

按行读取变量的内容, 一行接一行(类似于文件读取循环). 文件可以通过 FileRead 加载到变量中.

    Loop, parse, FileContents, `n, `r  ; 在 `r 之前指定 `n, 这样可以同时支持对 Windows 和 Unix 文件的解析.
    {
        MsgBox, 4, , Line number %A_Index% is %A_LoopField%.`n`nContinue?
        IfMsgBox, No, break
    }

除了用于剪贴板外, 这个例子和上一个一样. 每当剪贴板包含文件时这个例子很有用, 例如从打开的资源管理器窗口复制的文件(程序自动把这些文件转换为它们的文件名).

    Loop, parse, clipboard, `n, `r
    {
        MsgBox, 4, , File number %A_Index% is %A_LoopField%.`n`nContinue?
        IfMsgBox, No, break
    }

解析值由逗号分隔的文件(CSV).

    Loop, read, C:\Database Export.csv
    {
        LineNumber := A_Index
        Loop, parse, A_LoopReadLine, CSV
        {
            MsgBox, 4, , Field %LineNumber%-%A_Index% is:`n%A_LoopField%`n`nContinue?
            IfMsgBox, No
                return
        }
    }

判断遇到了哪个分隔符.

    ; 初始化要搜索的字符串.
    Colors = := "red,green|blue;yellow|cyan,magenta"
    ; 初始化计数器来跟踪字符串中我们的位置.
    Position := 0

    Loop, Parse, Colors, `,|;
    {
        ; 计算在这个字段末尾分隔符的位置.
        Position += StrLen(A_LoopField) + 1
        ; 获取解析循环中找到的分隔符.
        Delimiter := SubStr(Colors, Position, 1)

        MsgBox Field: %A_LoopField%`nDelimiter: %Delimiter%
    }

dftg