检查正则表达式是否不明确



我想知道是否有一种方法可以自动检查正则表达式的模糊性。如果正则表达式中有一个字符串可以通过多种方式进行匹配,则该正则表达式被认为是不明确的。例如,给定一个正则表达式R = (ab)*(a|b)*,我们可以检测到R是一个不明确的正则表达式,因为有两种方法可以匹配R中的字符串ab

更新

问题是如何检查正则表达式的定义是否不明确。我知道在regex机制的实际实现中,总是有一种方法可以匹配regex,但请以学术的方式阅读并思考这个问题。

正则表达式是一个不明确的当且仅当对应的Glushkov自动机不是确定性的。这可以在线性时间内完成。这是一个链接。顺便说一句,确定性正则表达式也以一个不明确性的名义进行了研究。

你忘记了贪婪。通常情况下,一个部分会获得优先权,因为这是一个贪婪的匹配,所以没有歧义。

相反,如果你谈论的是一个神话般的模式匹配引擎,而没有贪婪等实际细节;那么答案是肯定的,你可以。

采用图案中的每一个元素。并对每个可能的字符串尝试每个可能的子集。如果有多个子集与同一模式匹配,则存在歧义。对其进行优化,使其花费的时间少于无限长,留给读者练习。

我读了一篇发表在1980年左右的论文,该论文表明正则表达式是否是模糊的可以在O(n^4)时间内确定。我希望我能给你一个推荐人,但是我不再知道参考资料,甚至不知道日记。确定正则表达式是否不明确的一种更昂贵的方法是构造有限状态机(在最坏的情况下是时间和空间上的指数)。现在考虑由nfa状态N构造的FSM的任何状态X。如果,对于X的任意两个nfa状态n1,n2,follow(n1)相交follow(n2)不为空,则正则表达式不明确。如果FSM的任何状态都不是这样,那么正则表达式并不含糊。

一个可能的解决方案:

为正则表达式构造一个NFA。然后分析NFA,从一组仅由初始状态组成的状态开始。然后进行深度或宽度优先遍历,跟踪是否可以处于多个状态。您还需要跟踪所走的路径,以消除循环。

例如,您的(ab)*(a|b)*可以用三种状态进行建模。

 |   a   |   b
p| {q,r} |  {r}
q|  {}   |  {p}
r|  {r}  |  {r}

其中p是起始状态,p和r接受。

然后,您需要考虑这两个字母,并继续使用集合{q,r}和{r}。集合{r}只导致{r}给出一个循环,我们可以关闭该路径。集合{q,r},从{q,r}a带我们到{r},这是一个可接受的状态,但由于如果我们从去q开始,这条路径是不可接受的,我们这里只有一条路径,然后我们可以在识别循环时关闭它。从{q,r}中得到一个b将我们带到{p,r}。由于这两种接受,我们已经确定了ambigus位置,我们可以得出regexp是ambigus的结论。

最新更新