快速入门
教程
工具和语言
示例
参考
书评
正则表达式教程
简介
目录
特殊字符
不可打印字符
正则表达式引擎内部
字符类
字符类减法
字符类交集
简写字符类
词边界
交替
可选项
重复
分组和捕获
反向引用
反向引用,第 2 部分
命名组
相对反向引用
分支重置组
自由间距和注释
Unicode
模式修饰符
原子分组
占有量词
前瞻和后顾
环顾,第 2 部分
将文本排除在匹配之外
条件
平衡组
递归
子例程
无限递归
递归和量词
递归和捕获
递归和反向引用
递归和回溯
POSIX 方括号表达式
零长度匹配
继续匹配
本网站上的更多内容
简介
正则表达式快速入门
正则表达式教程
替换字符串教程
应用程序和语言
正则表达式示例
正则表达式参考
替换字符串参考
书评
可打印 PDF
关于本网站
RSS 源和博客
RegexBuddy—Better than a regular expression tutorial!

竖线或管道符号表示交替

我已经解释了如何使用 字符类 从多个可能的字符中匹配单个字符。交替类似。可以使用交替从多个可能的正则表达式中匹配单个正则表达式。

如果要搜索文本原义 catdog,请使用竖线或管道符号分隔两个选项:cat|dog。如果需要更多选项,只需展开列表:cat|dog|mouse|fish

交替运算符在所有正则表达式运算符中优先级最低。也就是说,它告诉正则表达式引擎匹配竖线左边的所有内容,或竖线右边的所有内容。如果你想限制交替的范围,你需要使用括号进行分组。如果我们想改进第一个示例以仅匹配整个单词,我们需要使用 \b(cat|dog)\b。这告诉正则表达式引擎查找单词边界,然后是 catdog,再然后是另一个单词边界。如果我们省略括号,则正则表达式引擎将搜索单词边界后跟 cat,或 dog 后跟单词边界。

记住正则表达式引擎是急切的

我已经解释过正则表达式引擎是急切的。它在找到有效匹配后立即停止搜索。其结果是在某些情况下,备选方案的顺序很重要。假设你想使用正则表达式匹配编程语言中的函数名称列表:Get、GetValue、Set 或 SetValue。显而易见的解决方案是 Get|GetValue|Set|SetValue。让我们看看当字符串为 SetValue 时它是如何工作的。

正则表达式引擎从正则表达式中的第一个标记 G 和字符串中的第一个字符 S 开始。匹配失败。然而,正则表达式引擎在开始之前研究了整个正则表达式。因此它知道此正则表达式使用交替,并且整个正则表达式尚未失败。因此它继续使用第二个选项,即正则表达式中的第二个 G。匹配再次失败。下一个标记是正则表达式中的第一个 S。匹配成功,引擎继续使用字符串中的下一个字符以及正则表达式中的下一个标记。正则表达式中的下一个标记是刚刚成功匹配的 S 之后的 ee 匹配 e。下一个标记 t 匹配 t

此时,交替中的第三个选项已成功匹配。由于正则表达式引擎很急切,因此只要其中一个选项匹配成功,它就会认为整个交替都已成功匹配。在此示例中,交替之外没有其他标记,因此整个正则表达式已成功匹配了 SetValue 中的 Set

与我们的预期相反,正则表达式并未匹配整个字符串。有几种解决方案。一种选择是考虑到正则表达式引擎很急切,并更改选项的顺序。如果我们使用 GetValue|Get|SetValue|Set,则在 Set 之前尝试 SetValue,并且引擎将匹配整个字符串。我们还可以将四个选项合并为两个,并使用 问号 使其中一部分变为可选:Get(Value)?|Set(Value)?。由于问号是贪婪的,因此在 Set 之前尝试 SetValue

最佳选择可能是表达我们只想匹配完整单词这一事实。如果字符串是 SetValueFunction,我们不想匹配 Set 或 SetValue。因此,解决方案是 \b(Get|GetValue|Set|SetValue)\b\b(Get(Value)?|Set(Value)?)\b。由于所有选项的结尾相同,因此我们可以进一步优化为 \b(Get|Set)(Value)?\b

文本定向引擎返回最长匹配

交替是 正则表达式定向和文本定向引擎有所不同 的地方。当文本定向引擎在 SetValue 上尝试 Get|GetValue|Set|SetValue 时,它会在字符串开头尝试正则表达式的所有排列。它高效地执行此操作,没有任何回溯。它看到正则表达式可以在字符串开头找到匹配项,并且匹配的文本可以是 SetSetValue。由于文本定向引擎将正则表达式作为一个整体进行评估,因此它没有一个备选方案在另一个方案之前列出的概念。但它必须选择返回哪个匹配项。它始终返回最长的匹配项,在本例中为 SetValue

POSIX 要求最长匹配

POSIX 标准 将选择文本导向引擎还是正则表达式导向引擎的权利留给了实现。包含反向引用的 BRE 需要使用正则表达式导向引擎进行评估。但是,不带反向引用的 BRE 或 ERE 可以使用文本导向引擎进行评估。但是,POSIX 标准确实要求返回最长匹配,即使使用了正则表达式导向引擎。这样的引擎不能急于求成。即使在找到匹配项之后,它也必须继续尝试所有备选方案,以便找到最长的匹配项。当正则表达式包含多个量词或量词和交替的组合时,这会导致非常差的性能,因为必须尝试所有组合才能找到最长匹配项。

TclGNU 风格也采用这种方式。