【regex】如何判断正则引擎是 DFA 还是 NFA

版权声明:欢迎转载,但请注明出处 https://blog.csdn.net/HaoDaWang/article/details/82934974

【regex】如何判断正则引擎是 DFA 还是 NFA

一般的正则引擎会分为 NFA, DFAPOSIX NFA,为了区分,前者被称作传统 NFANFADFA经常被类比为烧汽油的汽车和烧电的,烧电的一般看着会高档很多,烧汽油的乍一看会笨重很多,但是笨重,就有丰富的元字符的支持,两者在实现上也各有千秋,下面先看一下如何判断正则引擎是 DFA 还是 NFA。

如何判断

首先需要明确的是,DFA并不支持忽略优先量词,因此,判断你当前的正则引擎支不支持忽略优先量词,基本就能确定了。还有一种方法,可以使用多选结构来判断。

写一个简单的字符串

nfa not

用正则(nfa | nfa not)去匹配。

如果正则引擎是 NFA ,那么将会匹配到 “nfa”,如果是DFA,那么将会匹配到 “nfa not”,这和NFADFA的匹配机制有关。

如果正则引擎是 NFANFA开始匹配的时候,由于是多选结构,NFA通常会从左往右依次尝试,如果匹配失败,则回溯到多选结构前,然后开始尝试第二个,当匹配这个串时,nfa 匹配成功!就不会接着往后匹配了,返回结果。

如果正则引擎是DFADFA会始终选择长度最长的多选结构的选项,这是啥意思?DFA在编译正则的时候,会首先做一系列的优化措施,以便后面的匹配更加轻松,于是,说出来你们可能不信,DFA会记得所有的匹配可能,那么它的匹配过程大概是这样的。
刚开始匹配到 “nfa”,匹配成功,但是它发现往后也能继续匹配成功,于是最终匹配到 “nfa not”。

这也是为啥DFA要比NFA快很多的原因了。一般来说,回溯是NFA的灵魂,DFA中没有回溯,因为它从一开始就知道正则的所有结果,所以正则的好坏是不会影响DFA的,但是会影响NFANFA总会给人一种“不到黄河不死心”的感觉。一般的,NFA去匹配的话,如果匹配失败,NFA会尝试回溯,因为它并不知道后面还有没有可能匹配成功,他是蒙在鼓里的,但是DFA从一开始就知道,所有的匹配可能。

猜你喜欢

转载自blog.csdn.net/HaoDaWang/article/details/82934974