正则表达式 - 奇怪的行为
Regular expression - Strange behavior
我正在写一个编译器。我刚刚开始,所以我正在创建扫描仪(或词法分析器)。目前,我正在编写一些将由我的扫描仪处理的常规定义。尝试创建其中之一,我 运行 在下一个问题中:
我在 RegExr 中测试了以下(极其简单的)正则表达式:
r = /(a|ab)/
其中"r"是正则定义;我的意思是,正则表达式就是 (a|ab)
.
我认为语言 L(r) 应该是(根据书 Compilers: Principles, Techniques and Tools):
L(r) = {a, ab}
令人惊讶的是,该工具匹配 {a}
!
所以我的问题是,为什么会出现这种行为?
正则表达式从左到右解析文本,如果是交流发电机 (|
),它将首先匹配第一个候选者。
如果您使用:
(ab|a)
它将匹配 ab
和 a
。
关键是一旦找到匹配项,全局匹配器将在第一个匹配项结束后开始下一个匹配项尝试。
您可以轻松验证匹配的语言是 {a,ab}
:使用正则表达式 ^c(a|ab)d
并使用 cabd
。在这种情况下,正则表达式别无选择,只能选择第二个选项。
假设正则表达式为:(a|ab)
,文本为 ab
。它将与 a
匹配,接下来它将在 a
之后开始,因此它将尝试与 b
匹配,但失败。
然而,大多数词法分析器工具使用不同的方式来确定匹配。对于词法分析器工具,“最长匹配”很重要。所以匹配最长的字符数。
现在,如果您输入 (a|ba)
作为正则表达式,它将更早匹配 ba
。为什么?因为它的目的也是为了找到第一个尝试。在文本 cbad
中,从索引 1
(b
) 开始被认为比从索引 2
(a
) 开始更好。
正则表达式 a|ab
匹配 "a" 或 "ab"(很明显),但某些 tools/languages(例如 Java)认为输入匹配时整个 输入与正则表达式匹配,而其他(例如Java脚本)在 一些 输入匹配时考虑输入匹配。
您的工具必须是 "some" 品种才能匹配“{a}”。
正如@bohemian 所说,一些正则表达式只评估字符串的一部分,如果你想匹配整个字符串,你可以使用这样的正则表达式:
/^(a|ab)$/
只接受 a 或 ab
我正在写一个编译器。我刚刚开始,所以我正在创建扫描仪(或词法分析器)。目前,我正在编写一些将由我的扫描仪处理的常规定义。尝试创建其中之一,我 运行 在下一个问题中:
我在 RegExr 中测试了以下(极其简单的)正则表达式:
r = /(a|ab)/
其中"r"是正则定义;我的意思是,正则表达式就是 (a|ab)
.
我认为语言 L(r) 应该是(根据书 Compilers: Principles, Techniques and Tools):
L(r) = {a, ab}
令人惊讶的是,该工具匹配 {a}
!
所以我的问题是,为什么会出现这种行为?
正则表达式从左到右解析文本,如果是交流发电机 (|
),它将首先匹配第一个候选者。
如果您使用:
(ab|a)
它将匹配 ab
和 a
。
关键是一旦找到匹配项,全局匹配器将在第一个匹配项结束后开始下一个匹配项尝试。
您可以轻松验证匹配的语言是 {a,ab}
:使用正则表达式 ^c(a|ab)d
并使用 cabd
。在这种情况下,正则表达式别无选择,只能选择第二个选项。
假设正则表达式为:(a|ab)
,文本为 ab
。它将与 a
匹配,接下来它将在 a
之后开始,因此它将尝试与 b
匹配,但失败。
然而,大多数词法分析器工具使用不同的方式来确定匹配。对于词法分析器工具,“最长匹配”很重要。所以匹配最长的字符数。
现在,如果您输入 (a|ba)
作为正则表达式,它将更早匹配 ba
。为什么?因为它的目的也是为了找到第一个尝试。在文本 cbad
中,从索引 1
(b
) 开始被认为比从索引 2
(a
) 开始更好。
正则表达式 a|ab
匹配 "a" 或 "ab"(很明显),但某些 tools/languages(例如 Java)认为输入匹配时整个 输入与正则表达式匹配,而其他(例如Java脚本)在 一些 输入匹配时考虑输入匹配。
您的工具必须是 "some" 品种才能匹配“{a}”。
正如@bohemian 所说,一些正则表达式只评估字符串的一部分,如果你想匹配整个字符串,你可以使用这样的正则表达式:
/^(a|ab)$/
只接受 a 或 ab