JobPlus知识库 互联网 其它 文章
正则表达式(Regular Expression)-(4)表达式引擎

DFA和NFA

根据正则表达式的匹配方式不同,将正则表达式引擎分成文本模式(Text Directed)和表达式模式(Regex Directed)两种。有时候也称为DFA(Deterministic Finite Automaton 确定有穷状态机)、NFA(Nondeterministic Finite Automaton 不确定有穷状态机)。

NFA

NFA是基于表达式做匹配的。由于NFA支持惰性、引用等特性,所以NFA的应用比较广。事实上常见的正则表达式引擎都是NFA模式的。

我们来看一下正则表达式`ab*c`在引擎内部是如何匹配字符串“abbc”的。

1. 首先使用`a`匹配字符串"abbc"。

使用`a`匹配,字符串字符“a”,匹配。

2. 使用`b*`匹配剩余字符串“bbc”。

使用`b*`匹配字符串第一个“b”,匹配。

继续使用`b*`匹配字符串第二个“b”,匹配。

继续使用`b*`匹配字符串“c”,不匹配。剩余字符串为“c”。

3. 使用`c`匹配剩余字符串“c”。

使用`c`匹配,字符串字符“c”,匹配。正则表达式匹配成功。

NFA的回溯

如果正则式出现了重复符号或选择符号,则正则表达式可能会出现多种匹配的结果,而NFA是使用回溯来实现对所有正则表达式可能出现的结果进行遍历的。

我们看一下,利用正则表达式`a.+c`查找字符串“abcd”,表达式引擎是如何查找的。

1. 子表达式`a`匹配字符“a”。剩余字符串“bcd”

2. 子表达式`.+`可以匹配剩余字符串"bcd",一直到字符串结束。剩余字符串为空。

3. 子表达式`c`匹配字符串结束,不匹配。促发上一个子表达式回溯。

4. 上一个子表达式`.+`退回一个字符“d”,即匹配字符串“bc”。剩余字符串“d”。

5. 子表达式`c`匹配剩余字符串“d”,不匹配。再次促发上一个匹配回溯。

6. 上一个子表达式`.+`再退回一个字符“c”,即匹配字符串“b”。剩余字符串“cd”。

7. 子表达式`c`匹配剩余字符串“cd”,匹配“c”。字符串匹配成功。

DFA

DFA是基于文本的匹配引擎。由于DFA没有回溯等操作,所以DFA的速度较之于NFA要快。

我们来看一下正则表达式`ab*c`是如何匹配字符串“abbc”的。

1. 首先使用`a`匹配字符串"abbc"。

使用`a`匹配,字符串字符“a”,匹配。剩余字符串为“bbc”。

2. 使用`b*`匹配剩余字符串“bbc”。

使用`b*`作为空字符匹配空字符,匹配。这个结果备选,剩余字符串为“bbc”.

继续使用`b*`匹配字符串第一个“b”,匹配。这个结果备选,剩余字符串为“bc”。

继续使用`b*`匹配字符串第二个“b”,匹配。这个结果备选,剩余字符串为“c”。

继续使用`b*`匹配字符串“c”,不匹配。这个结果不使用。

3. 使用`c`匹配剩余字符串“bbc”、“bc”或“c”。

使用`c`匹配,字符串字符“bbc”,不匹配。这个结果不使用。

使用`c`匹配,字符串字符“bc”,不匹配。这个结果不使用。

使用`c`匹配,字符串字符“c”,匹配。正则表达式匹配成功。

DFA的最长匹配

如果正则式出现了重复符号或选择符号,则正则表达式可能会出现多种匹配的结果,在DFA中,会选择其中最长的匹配结果。

例如,用正则表达式`HashMap|LinkedHashMap`匹配字符串“LinkedHashMap”。两个子表达式`HashMap`和`LinkedHashMap`都可以匹配。DFA会选择最长的匹配"LinkedHashMap"。




如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
97人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序