# Loop Parse

每次从字符串中检索字符串(片段).

    Loop Parse String , Delimiters, OmitChars

## 参数

String

  类型: 字符串

  要分析的字符串.

Delimiters

  类型: 字符串

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

  如果此参数为 `"CSV"`, 字符串将以标准的逗号分隔值格式进行解析. 下面是一个由 MS Excel 生成的 CSV 行的示例:

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

  否则, Delimiters 包含一个或多个字符(区分大小写), 每个字符用于确定子串之间的边界位置.

  定界符不被认为是子串本身的一部分. 此外, 如果输入字符串中的一对定界符之间没有任何内容, 那么相应的子串将是空的.

  例如: `','`(逗号) 会根据每一个逗号的出现来划分字符串. 类似地, `A_Tab A_Space` 会在每次输入字符串中出现空格或制表符时开始一个新的子串.

  要使用字符串作为定界符而不是字符, 首先使用 StrReplace 将所有出现的字符串替换为从未在文本中使用过的单个字符, 例如, 这些特殊字符之一: ¢¤¥¦§©ª«®µ¶. 考虑这个示例, 它使用字符串 <br> 作为分隔符:

      NewHTML := StrReplace(HTMLString, "<br>", "¢")
      Loop Parse, NewHTML, "¢" ; 使用 ￠ 解析字符串.
      {
      ...
      }

OmitChars

  类型: 字符串

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

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

## 备注

当你想对一个字符串中包含的每一个片段进行操作时, 字符串解析循环很有用. 解析循环比 StrSplit 使用更少的内存且在大多数情况下更容易使用(尽管无论哪种方式使用的内存都是暂时的).

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

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

输入字符串或其片段没有大小限制.

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

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

循环的后面有一个可选的 Else 语句, 如果循环的迭代次数为零, 则执行 Else 语句. 注意, 除非 String 为空或者省略了 Delimiters 并且 String 中的所有字符都包含在 OmitChars 中, 否则循环总是至少有一次迭代.

## 相关

StrSplit, file-reading loop, Loop, Break, Continue, 区块, Sort, FileSetAttrib, FileSetTime

## 示例

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

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

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

    Loop parse, FileContents, "`n", "`r"  ; 在 `r 之前指定 `n, 这样可以同时支持对 Windows 和 Unix 文件的解析.
    {
        Result := MsgBox("Line number " A_Index " is " A_LoopField ".`n`nContinue?",, "y/n")
    }
    until Result = "No"

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

    Loop parse, A_Clipboard, "`n", "`r"
    {
        Result := MsgBox("File number " A_Index " is " A_LoopField ".`n`nContinue?",, "y/n")
    }
    until Result = "No"

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

    Loop read, "C:\Database Export.csv"
    {
        LineNumber := A_Index
        Loop parse, A_LoopReadLine, "CSV"
        {
            Result := MsgBox("Field " LineNumber "-" A_Index " is:`n" A_LoopField "`n`nContinue?",, "y/n")
            if Result = "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