有没有办法找出两个任意正则表达式是否相同?看起来像复杂的问题,但可能有一些DFA简化机制或什么?
答案 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 a
和b b
但不是b a
和a b
)分隔的同一单词的双重出现。有些自动机根本无法识别。
答案 3 :(得分:1)
这两个Perlmonks线程讨论了这个问题(具体来说,请阅读blokhead的回复):