RegExMatch() [v1.0.45+]

优质
小牛编辑
131浏览
2023-12-01

判断字符串是否包含某个匹配模式(正则表达式)。

FoundPos := RegExMatch(Haystack, NeedleRegEx [, UnquotedOutputVar = "", StartingPosition = 1])

参数

FoundPos

RegExMatch() 返回 NeedleRegEx 在字符串 Haystack 中最左边的出现位置. 首个字符位置为 1. 如果没有找到匹配模式则返回零. 如果遇到错误 (例如 NeedleRegEx 出现语法错误), 则返回空字符串并设置 ErrorLevel 为 下列 值的其中一个而不是 0.

Haystack

源字符串.

NeedleRegEx

要搜索的模式, 它是兼容 Perl 的正则表达式 (PCRE). 模式的选项(如果有)必须放在模式字符串的开始且后面跟着闭括号。例如, 模式 "i)abc.*123" 将匹配不区分大小写的 "abc", 接着零个或多个任意字符, 并以 "123" 结尾的字符串. 如果不含选项, 则可以省略 ")"; 例如, ")abc" 等同于 "abc".

UnquotedOutputVar

模式 1 (默认): OutputVar 是用来保存 Haystack 中匹配整个模式的那部分的变量名. 如果没有找到模式 (即如果函数返回 0), 则此变量和下面的所有数组元素都被置空.

如果在 NeedleRegEx 中包含捕获子模式,那么它们的匹配将被存储在基名称为 OutputVar伪数组里。例如, 如果输出变量名是 Match, 则匹配首个子模式的子字符串存储在 Match1, 第二个存储在 Match2, 依此类推. 这种情况的例外是 命名子模式: 它们以名称而不是数字保存. 例如,匹配命名子模式“(?P<Year>\d{4})”的子字符串存储在 MatchYear。如果特定的子模式不匹配任何文本 (或如果函数返回零), 则相应的变量被置空.

函数中,要创建全局而不是局部的伪数组,则必须在使用前声明伪数组的基名称(例如 Match)为全局变量。对于 假设全局 函数, 反之亦成.

模式 2 (位置和长度): 如果在正则表达式选项中含有 P (例如 "P)abc.*123"), 则整个模式的匹配字符串的 长度 会被存储到 OutputVar (如果没有匹配则为 0). 如果包含捕获子模式,则它们匹配的位置和长度会被存储到两个伪数组OutputVarPosOutputVarLen。例如,如果变量的基名称为 Match,首个子模式的匹配位置(基于 1)会存储在 MatchPos1,而它的长度存储在 MatchLen1(如果子模式没有匹配或函数返回 0 则它们两者中保存的都为零)。这种情况的例外是命名子模式:它们以名称而不是数字保存(例如 MatchPosYearMatchLenYear)。

模式 3 (匹配对象) [v1.1.05+]: 如果在正则表达式选项中含有大写的 O (例如 "O)abc.*123"), 则 匹配对象 会被存储到 UnquotedOutputVar. 此对象还可以用来获取整个匹配和每个捕获子模式(如果存在)的位置、长度和值。

StartingPosition

如果省略 StartingPosition, 则它默认为 1 (从 Haystack 的首个字符开始). 否则, 从第二个字符开始请指定 2, 第三个开始为 3, 依此类推. 如果 StartingPosition 超过了 Haystack 的长度, 则搜索会从 Haystack 末尾后的空字符串开始 (这通常会导致没有匹配发生).

如果 StartingPosition 小于 1, 则它被视为从 Haystack 末尾开始的偏移. 例如, 0 表示从最后一个字符开始而 -1 则从倒数第二个字符开始. 如果 StartingPosition 超出了 Haystack 最左边的位置, 则会搜索整个 Haystack.

不论 StartingPosition 的值是多少, 返回的值总是相对与 Haystack 的首个字符. 例如, "abc" 在 "123abc789" 中的位置总为 4.

ErrorLevel

[v1.1.04+] 此函数失败时会抛出异常 (这个不会和 "没有找到匹配" 冲突, 失败表示匹配过程中遇到问题, 而 "没有找到匹配" 表示匹配过程成功完成只是没有发现匹配). 想了解更多信息, 请参阅 运行时错误.

ErrorLevel 被设置为下列值的其中一个:

  • 0, 表示没有遇到错误.
  • 一个如下格式的字符串: Compile error N at offset M: description. 在此字符串中, N 是 PCRE 错误值, M 是正则表达式中出现错误的字符的位置, 而 description 是描述这个错误的文本.
  • 一个负数, 表示在正则表达式 执行 时遇到的错误. 尽管这样的错误很罕见, 然而像这些情况就容易出现这种错误, 例如 "太多空字符串匹配" (-22), "递归太深" (-21) 以及 "达到匹配限制" (-8). 如果出现这些情况, 请尝试重新设计更严格的匹配模式, 例如无论是否可行都把每个 * 替换为 ?, + 或像 {0,3} 这样的限制.

选项

请参阅 选项 了解修饰符, 例如 "i)abc", 里面的选项关闭了 "abc" 模式中的区分大小写匹配.

匹配对象 v1.1.05+

如果在正则表达式选项中含有大写的 O, 则匹配对象会被存储到 UnquotedOutputVar. 此对象含有下列属性:

Match.Pos(N): 返回整个匹配或捕获子模式的位置.

Match.Len(N): 返回整个匹配或捕获子模式的长度.

Match.Value(N): 返回整个匹配或捕获子模式.

Match.Name(N):返回指定的子模式的名称(如果它含有)。

Match.Count(): 返回所有子模式的数目.

Match.Mark():适用时返回上次遇到 (*MARK:NAME)NAME

Match[N]: 如果 N 为 0 或有效的子模式编号或名称, 那么它相当于 Match.Value(N). 否则, N 可以为上面其中一个属性的名称. 例如, Match["Pos"]Match.Pos 相当于 Match.Pos(), 不过如果存在名称为 "Pos" 的子模式, 此时它们相当于 Match.Value("Pos").

Match.N: 与上面相同, 不过这里 N 为未引用的名称或编号.

对于上面的所有属性, 其中 N 可以为下列值:

  • 0 表示整个匹配.
  • 子模式的编号, 包括含有名称的子模式.
  • 子模式的名称.

如果指定了 N, 则可以使用方括号 [] 代替其中的圆括号.

性能

要在一个较大的字符串中搜索简单的子字符串, 请使用 InStr(), 因为它比 RegExMatch() 执行地更快.

为了提升性能, 最近使用的 100 个正则表达式会被缓存在内存中 (以已编译的形式).

多次使用一个正则表达式时 (例如在循环中), 使用 研究选项 (S) 可以提高性能.

备注

可以为子模式指定名称,例如模式“(?P<Year>\d{4})”中的 Year。这种名称最多可以由 32 个字母数字和下划线组成. 下面的限制不适用于“O”(匹配对象)模式:尽管命名的子模式在正则表达式运算时还可以使用它们的编号(例如 \1 为到实际匹配首个捕获子模式的字符串的后向引用),然而它们被存储到输出伪数组时通过名称(而不是编号)。例如,如果“Year”是首个子模式,则 OutputVarYear 会被设置为匹配的子字符串,但 OutputVar1 不会发生变化(如果有则它会保持原来的值)。然而,如果在“Year”后含有未命名子模式,则它会被存储到 OutputVar2,而不是 OutputVar1

大多数字符 (例如 abc123) 可以直接使用在正则表达式中. 然而, \.*?+[{|()^$ 这些字符则必须在其前面加上反斜线来进行匹配. 例如, \. 表示一个原义的句点而 \\ 表示一个原义的反斜线. 使用 \Q...\E 能避免转义. 例如:\QLiteral Text\E

在正则表达式中, 特殊字符 (如制表符和新行符) 可以使用一个重音符 (`) 或反斜线 (\) 进行转义. 例如, 不含 x 选项时 `t 等同于 \t.

要了解正则表达式的基础 (或复习正则表达式的语法), 请参阅 正则表达式快速参考.

AutoHotkey 的正则表达式是使用来自 www.pcre.org 的兼容 Perl 的正则表达式 (PCRE) 实现的.

相关

RegExReplace(), 正则表达式快速参考, 正则表达式调出, InStr(), IfInString, StringGetPos, SubStr(), SetTitleMatchMode RegEx, 全局匹配和 Grep (论坛链接)

文本数据的常见来源: FileRead, UrlDownloadToFile, Clipboard, GUI Edit 控件

示例

FoundPos := RegExMatch("xxxabc123xyz", "abc.*xyz")  ; 返回 4, 这是找到匹配的位置.
FoundPos := RegExMatch("abc123123", "123$")  ; 返回 7, 因为 $ 要求在末端进行匹配.
FoundPos := RegExMatch("abc123", "i)^ABC")  ; 返回 1, 因为通过不区分大小写选项实现了匹配.
FoundPos := RegExMatch("abcXYZ123", "abc(.*)123", SubPat)  ; 返回 1, 并把 "XYZ" 保存到 SubPat1.
FoundPos := RegExMatch("abc123abc456", "abc\d+", "", 2)  ; 返回 7 而不是 1, 这是由于 StartingPosition 为 2 而不是 1.

; 关于普通正则表达式的例子, 请参阅 正则表达式快速参考.