正则引擎的介绍
正则引擎主要分为基本不同的两大类:一种是DFA
引擎,可类比于电动汽车的电动发动机;另一种则是我们要详细讲解的NFA
引擎,可类比于汽车的汽油发动机!两类引擎都有很长的历史,不过,正如汽油发动机一样,NFA
引擎的历史更长一些,当今的绝大多数主流编程语言采用的也是NFA
引擎,下表列举了一些主流的编程语言或工具采用的正则引擎:
正则引擎类型 | 编程语言或工具 |
---|---|
DFA | MySQL 、flex 、lex 、egrep |
POSIX NFA | mawk 、GNU Emacs |
传统型NFA | Perl 、Java 、JavaScript 、Python 、C 、C# 、C++ 、PHP 、Ruby 、.Net |
NFA/DFA混合 | GNU awk 、Tcl |
JavaScript
采用的正则引擎是传统型NFA
引擎,NFA
引擎是基于表达式的匹配,这和基于文本的匹配的DFA
引擎是完全不同的,NFA
引擎与 DFA
引擎的区别有很多,让我对比来了解NFA
引擎:
NFA
与 DFA
在预编译期的区别
在预编译期间,通常NFA
的编译速度快于DFA
,占用的内存也更少!
NFA
与DFA
在匹配速度上的区别
在匹配速度上,由于NFA
是基于表达式的匹配,在报告无法匹配之前,必须尝试正则表达式的所有变体,所以,通常NFA
的匹配速度慢于DFA
!
NFA
与DFA
在匹配结果上的区别
在匹配结果上,DFA
或者POSIX NFA
会返回最左边的最长的匹配文本,匹配结果是确定的,而传统型NFA
则不一定返回这样的文本,也可能是其它文本,所以传统型NFA
的匹配结果是不确定的!
NFA
与DFA
在能力上的区别
NFA
提供了一些DFA
不支持的功能:捕获分组、环视及其它复杂的零长度确认、忽略优先量词及有序的多选分支结构(POSIX NFA
也不支持此功能)、占有优先量词、固化分组!
在不考虑NFA/DFA混合
引擎的情况下,很容易发现:
- 若引擎支持
忽略优先量词(非贪婪模式)
,则该引擎一定是传统型NFA
引擎; - 若引擎不支持
忽略优先量词(非贪婪模式)
,但是支持捕获分组
和回溯
,则该引擎一定是POSIX NFA
引擎; - 若引擎以上三个功能都不支持,则一定是
DFA
引擎。