2015-03-19 68 views
0

我正在编写一个编译器。我刚开始,所以我正在创建扫描仪(或Lexer)。目前,我正在编写一些将由我的扫描仪处理的常规定义。力图打造他们中的一个,我的下一个问题运行:正则表达式 - 奇怪的行为

我的测试,在RegExr,以下(非常简单)的正则表达式:

r = /(a|ab)/ 

其中“R”是一个普通的定义;我的意思是,正则表达式只是(a|ab)

我认为语言L(R)将是(按书Compilers: Principles, Techniques and Tools):

L(r) = {a, ab} 

出人意料的是,该工具相匹配{a}

所以我的问题是,为什么会这样?

+0

在正则表达式中'''是一个交流发电机,即你的正则表达式将匹配'a'或'ab'。你想让它匹配'a' _跟着by_'ab'吗? – 2015-03-19 13:12:18

+0

嗨@JamesThorpe,其实我不想“找到”正则表达式。我在寻找的是理解上述奇怪的行为。 – 2015-03-19 13:14:38

回答

2

正则表达式a|ab匹配“a”或“AB”(明显),但一些工具/语言(如Java的)考虑输入时整个输入正则表达式匹配来匹配,而其他(如JavaScript)的考虑输入匹配时的一些匹配。

您的工具必​​须是“一些”品种以匹配“{a}”。

+0

你知道一个像Java正则表达式工具一样的在线工具吗? – 2015-03-19 13:23:03

+0

@LeonardoManrique不,但你可以通过在前面添加'^'并且在末尾添加'$'来实现它,例如'^ a | ab $'。顺便说一句你的正则表达式相当于'ab?' – Bohemian 2015-03-19 14:11:38

+0

你是指lexem?如果是这样,我不想将一个lexem与一个模式相匹配,我只是设计了常规定义。当我尝试使用该工具时,我用我们一直在讨论的“错误”来运行。如果你正在引用正则表达式本身,它就相当于'a'。 – 2015-03-19 15:16:23

1

正则表达式从左到右解析文本,如果是交流发电机(|),它将首先瞄准与第一个候选人匹配。

如果你使用:

(ab|a) 

将同时匹配aba的。

问题是,一旦找到匹配,全局匹配器将在第一次匹配结束后开始下一个匹配尝试

您可以轻松验证匹配的语言是{a,ab}:使用正则表达式^c(a|ab)d并使用cabd。在这种情况下,正则表达式别无选择,只能选择第二个选项。

所以说正则表达式如下:(a|ab)和文本是ab。它将与a相匹配,接下来将在a之后开始,因此它将尝试与b匹配,但失败。

然而,大多数词法分析器工具使用不同的方法来确定匹配。对于词法分析器工具,“最长匹配”是重要的。所以匹配的字符数最长。

现在,如果您输入(a|ba)作为正则表达式,它将与之前的ba匹配。为什么?因为它也旨在找到第一次尝试。并且在文本cbad中,从索引1b)开始被认为比起始于索引2a)更好。

+0

嗨CommuSoft。是的,你有权利,但如果我写这个正则表达式:(a | ba),该工具匹配{a,ba}。 – 2015-03-19 13:16:18

+0

@LeonardoManrique:它匹配buth。如果你使用'^(a | ab)$'并且匹配'ab',它将匹配。 – 2015-03-19 13:17:08

+1

@LeonardoManrique:抱歉,您的评论错了,请参阅修改后的答案。 – 2015-03-19 13:20:33

0

正如所说的@bohemian如果你想整个字符串匹配,你可以使用这样的正则表达式正则表达式的一些评估只是一个字符串的一部分:

/^(a|ab)$/ 

其中仅接受一个ab