正则表达式优化技巧总结
正则引擎的分类
正则引擎可以粗略地分为3类:
部分程序及其使用的正则引擎
DFA
awk(大多数版本)、egrep(大多数版本)、mysql
传统NFA
GNU Emacs、java、grep(大多数版本)、less、more、perl、PHP、sed、vi
POSIX NFA
mawk、GNU Emacs(明确指定时使用)
DFA/NFA混合
GNU awk、GNU grep/egrep
影响正则表达式匹配的重要概念--回溯
??? NFA引擎最重要的性质是,它会依次处理各个子表达式或组成元素,遇到需要在两个可能成功的可能中进行选择的时候,它会选择其一,同时记住另一个,以备稍后可能的需要。需要做出选择的情形包括量词(决定是否尝试另一次匹配) 和多选结构(决定选择哪个多选分去)。
??? 不论选择哪一种途径,如果它匹配成功,而且正则表达式的余下部分也成功了,匹配即告成功。如果正则表达式中余下的部分最终匹配失败,引擎会知道需要回溯到之前做出选择的地方,选择其他的备用分支继续尝试。这样引擎最终会尝试表达式的所有可能途径(或者是匹配完成之前需要的所有途径)。
??? 回溯的两个要点:
??? 如果需要在“进行尝试”和“跳过尝试”之间选择,对于匹配优先量词,引擎会优先选择“进行尝试”,而对于忽略优先量词,会选择“跳过尝试”。
距离当前最近储存的选项就是本地失败强制回溯时返回的。使用的原则是LIFO(后进先出)。
多选结构既不是匹配优先的,也不是忽略优先的,而是按顺序排列的,至少对传统型NFA来说是如此。也不是所有的流派都支持按序排列的多选结构。DFA和POSIX NFA确实有匹配优先的多选结构,它们总是匹配所有多选分支中能匹配最多文本的那个。但是,如果你使用的是Perl、PHP、.NET、java.util.regex,或者其他使用传统型NFA的工具,多选结构就是按序排列的。
??? 性能调优时评价的几个方面:
技巧:
实施优化时请谨记:有得必有失。实施了某个优化,可能对不同的正则引擎执行效率会产生很大的不同。请谨慎测试。
?