3.正则引擎:
最近在看《精通正则表达式》(虽然这本书并没有提到js,然后译者自己出了本差不多的书把js写进去了)(在图书馆的我一脸蒙蔽还是借了这本)(还是想问作者为什么要用车做比喻,我好好的学习编程之前还得去学个车不成??)
这本书有提到正则引擎,原来正则引擎有几种那么多,基于不同的引擎,构建正则表达式的方式决定了某个正则表达式能否匹配一个特定字符串,在何处匹配,以及匹配成功或报告失败的速度。
正则引擎主要有:DFA(确定型有穷自动机),传统型NFA(非确定型有穷自动机),POSIX NFA(可以看作是比较厉害的升级版加速NFA)。
那书上也没写js,怎么js是什么引擎嘞。测一测嘛。
console.log("nfa not".match(/nfa|nfa not/)); //nfa
好了嘛,是nfa,那是哪个nfa呢
console.time('/X(.+)+X/ test');
"==XX=============================".match(/X(.+)+X/);
console.timeEnd('/X(.+)+X/ test'); // /X(.+)+X/ test: 25191.253ms
时间挺长的哈,应该是传统型NFA了。
NFA是表达式主导引擎,每一个子表达式都是独立的,不存在内在联系。
NFA为什么叫NFA,不确定在哪里?表达式主导,意味着引擎在匹配文本时,都要看看当前文本是否匹配正则表达式的当前部分(如果有子表达式的分支,会检测逐个分支,如果某一分支不匹配,就尝试另一个分支元素)。表达式的控制权在不同的元素之间转换,所以是表达式主导。
如果你了解DFA,就知道它是文本式主导,没有回溯和捕获式分组,这意味着它不需犹豫不决。
而NFA,则是“不到黄河心不死”,直到抵达正则表达式的末尾前,匹配的结果都是不确定的。
既然NFA具备回溯机制,那么我们细细来说,NFA是怎么回溯,回溯到哪里的。
回溯相当于在走一条陌生的路时,边走边做标记。就好像我玩RPG游戏的时候非常怂,总之S\L大法好。在它们正则界官方,这叫做备用状态。
根据《精通正则表达式》这本书的例子,我自己再模仿着画了一次图帮助记忆和理解。
这是?匹配符的例子(字丑,尴尬,数位板最近不好使)
而*号每次测试它作用的元素时之前,引擎都会保存一个状态
+号是匹配第一个元素后再依照*号的类似规则保存状态。
然而这里有一个特殊的例子,正则表达式/[0-9]*/匹配‘abc123456’的时候,会在1之前的位置保存一个备用状态吗?在正则表达式*后面还有别的子表达式的时候,会;如果整个正则表达式由*支配,则不保存。详见书本164页,因为我也不是理解得很透彻。。。
网友评论