正则表达式等价

时间:2009-02-18 08:35:08

标签: regex algorithm dfa

有没有办法找出两个任意正则表达式是否相同?看起来像复杂的问题,但可能有一些DFA简化机制或什么?

4 个答案:

答案 0 :(得分:10)

要测试等效性,您可以计算表达式的minimal DFAs并进行比较。

答案 1 :(得分:10)

相等的可测性是正则表达式的经典属性之一。 (N.B.如果您真的在谈论Perl正则表达式或其他一些技术上非常规的超语言,那么这就不成立了。)

将你的RE转换为广义有限自动机A和B,然后构造一个新的自动机A-B,使得A的接受状态具有到B的起始状态的空转换,并且B的接受状态被反转。这为您提供了一个自动机,它接受A接受的所有字符串,但B接受的所有字符串除外。

对B-A执行相同操作,并将两者都减少为纯粹的FAs。如果FA没有从开始状态可访问的接受状态,则它接受空语言。如果您可以证明A-B和B-A都是空的,那么您已经证明A = B。

Edit嘿,我简直不敢相信没有人注意到那里的巨大错误 - 当然是故意错误:-p

如上所述的自动机A-B将接受那些前半部分被A接受且其后半部分未被B接受的字符串。构建期望的 A-B是一个稍微复杂的过程。我无法想到这一点,但我确实知道它的定义很明确(并且可能涉及创建状态代表接受A中的状态和B中的非接受状态的产品)。

答案 2 :(得分:2)

这实际上取决于正则表达式的含义。正如其他海报所指出的那样,将两个表达式都减少到它们的最小DFA应该有效,但它只适用于纯正则表达式。

在现实世界的正则表达式库中使用的一些构造(特别是反向引用)赋予它们表达非常规语言的能力,因此DFA算法不适用于它们。例如,正则表达式:([a-z]*) \1匹配由空格(a ab b但不是b aa b)分隔的同一单词的双重出现。有些自动机根本无法识别。

答案 3 :(得分:1)

这两个Perlmonks线程讨论了这个问题(具体来说,请阅读blokhead的回复):