# Loop (parse a string)

Retrieves substrings (fields) from a string, one at a time.

Loop, Parse, InputVar [, Delimiters, OmitChars]

#### Parameters

Parse | This parameter must be the word PARSE, and unlike other loop types, it must not be a variable reference that resolves to the word PARSE.
InputVar | The name of the variable whose contents will be analyzed. Do not enclose the name in percent signs unless you want the contents of the variable to be used as the name.
Delimiters | If this parameter is blank or omitted, each character of InputVar will be treated as a separate substring. If this parameter is CSV, InputVar will be parsed in standard comma separated value format. Here is an example of a CSV line produced by MS Excel: "first field",SecondField,"the word ""special"" is quoted literally",,"last field, has literal comma" Otherwise, Delimiters contains one or more characters (case sensitive), each of which is used to determine where the boundaries between substrings occur in InputVar. Delimiter characters are not considered to be part of the substrings themselves. In addition, if there is nothing between a pair of delimiters within InputVar, the corresponding substring will be empty. For example: `, (an escaped comma) would divide the string based on every occurrence of a comma. Similarly, %A_Tab%%A_Space% would start a new substring every time a space or tab is encountered in InputVar. To use a string as a delimiter rather than a character, first use StringReplace to replace all occurrences of the string with a single character that is never used literally in the text, e.g. one of these special characters: ¢¤¥¦§©ª«®µ¶. Consider this example, which uses the string <br> as a delimiter:
    StringReplace, NewHTML, HTMLString, <br>, ¢, All
    Loop, parse, NewHTML, ¢ ; Parse the string based on the cent symbol.
    {
    ...
    }
OmitChars | An optional list of characters (case sensitive) to exclude from the beginning and end of each substring. For example, if OmitChars is %A_Space%%A_Tab%, spaces and tabs will be removed from the beginning and end (but not the middle) of every retrieved substring. If Delimiters is blank, OmitChars indicates which characters should be excluded from consideration (the loop will not see them). Unlike the last parameter of most other commands, commas in OmitChars must be escaped (`,).

#### Remarks

A string parsing loop is useful when you want to operate on each field contained in a string, one at a time. Parsing loops use less memory than StringSplit (since StringSplit creates a permanent array) and in most cases they are easier to use.

The built-in variable A_LoopField exists within any parsing loop. It contains the contents of the current substring (field) from InputVar. If an inner parsing loop is enclosed by an outer parsing loop, the innermost loop's field will take precedence.

Although there is no built-in variable "A_LoopDelimiter", the example at the very bottom of this page demonstrates how to detect which delimiter was encountered for each field.

There is no restriction on the size of InputVar or its fields. In addition, if InputVar's contents change during the execution of the loop, the loop will not "see" the changes because it is operating on a temporary copy of the original contents.

To arrange the fields in a different order prior to parsing, use the Sort command.

See Loop for information about Blocks, Break, Continue, and the A_Index variable (which exists in every type of loop).

#### Related

StringSplit, file-reading loop, Loop, Break, Continue, Blocks, Sort, FileSetAttrib, FileSetTime

#### Examples

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

    ; Example #2: Read the lines inside a variable, one by one (similar to a file-reading loop).
    ; A file can be loaded into a variable via FileRead:
    Loop, parse, FileContents, `n, `r  ; Specifying `n prior to `r allows both Windows and Unix files to be parsed.
    {
        MsgBox, 4, , Line number %A_Index% is %A_LoopField%.`n`nContinue?
        IfMsgBox, No, break
    }

    ; Example #3: This is the same as the example above except that it's for the clipboard.
    ; It's useful whenever the clipboard contains files, such as those copied from an open
    ; Explorer window (the program automatically converts such files to their file names):
    Loop, parse, clipboard, `n, `r
    {
        MsgBox, 4, , File number %A_Index% is %A_LoopField%.`n`nContinue?
        IfMsgBox, No, break
    }

    ; Example #4: Parse a comma separated value (CSV) file:
    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
        }
    }

    ; The following example is similar to a parsing loop but also provides awareness
    ; of which delimiter was encountered.

    ; Initialize string to search.
    Colors = red,green|blue;yellow|cyan,magenta
    ; Initialize zero-based offset to begin search at.
    field_begin := 0
    ; Initialize delimiters.
    delimiters = ,|;
    Loop
    {
        ; Find zero-based index of next delimiter, relative to beginning of current field.
        field_length := DllCall("shlwapi\StrCSpnA", "uint", &Colors + field_begin, "uint", &delimiters, "uint")
        ; Extract field from input string.
        field := SubStr(Colors, field_begin + 1, field_length)
        ; Extract delimiter from input string.
        delimiter := SubStr(Colors, field_begin + field_length + 1, 1)

        MsgBox % "field: " field "`ndelimiter: " delimiter

        ; If delimiter is blank, StrCSpn reached the end of the input string.
        if delimiter =
            break
        ; Advanced to the beginning of the next field.
        field_begin += field_length + 1
    }