`
backkom1982
  • 浏览: 28037 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

正则表达式优化技巧总结

阅读更多

正则引擎的分类
正则引擎可以粗略地分为3类:

  • 以文本为主导的DFA(确定型有穷自动机)
  • 以正则表达式为主导的传统型NFA(非确定型有穷自动机)
  • POSIX NFA

部分程序及其使用的正则引擎

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的工具,多选结构就是按序排列的。

    性能调优时评价的几个方面:

  • 哪种引擎从中获益?传统型NFA、或者POSIX NFA,或者两者?
  • 什么情况下,这种修改带来的收益最大?在文本能够匹配时,无法匹配时,还是所有时候?


技巧:

  • 如果多选分支是有序的,而能够匹配同样文本的多选分支又不只一个,就要小心安排多选分支的先后顺序。
  • 加速某些操作。某些类型的匹配,例如\d+,极为常见,引擎可能对此有特殊的处理方案,执行速度比通用的处理机制要快。
  • 避免冗余操作。如果引擎认为,对于产生正确结果来说,某些特殊的操作是不必要的,或者某些操作能够应用到比之前更少的文本,忽略这些操作能够节省时间。例如,一个以\A开头的正则表达式只有在字符串的开头位置才能匹配,如果在此处无法匹配,传动装置不会徒劳地尝试其他位置。
  • 消除无必要括号。正则引擎对捕获型括号,每次匹配都会记录状态,回退时需要清除状态。除非必要尽量不要使用捕获型括号。
  • 消除不需要的字符组。比如使用转义后的\.代替[.]
  • 对(.+)*之类的量词结合结构,避免制造指级的回溯
  • 使用占有优先量词消减回溯状态
  • 使用起始锚点。某些正则引擎会对此类表达式进行匹配优化。
  • 提取多选开头的必须元素。比如用th(is|at)代替this|that
  • 根据具体情况分析,使用忽略优先还是匹配优先,或使用固化分组和占有优先量词,以减少回溯
  • 拆分正则表达式。有时,在代码里多次执行拆分后的正则表达式比用一个正则表达式完成的同样的功能,执行时间反而更少。
  • 将最可能匹配的多选分支放在前头
  • 消除循环:常用的解法是opening normal*(special normal)*closing。避免无休止匹配的三个要点:1)special部分和normal部分匹配的开头不能重合。2)normal部分必须匹配至少一个字符。3)special部分必须是固化的。 亦可使用固化分组和占有优先量词。




实施优化时请谨记:有得必有失。实施了某个优化,可能对不同的正则引擎执行效率会产生很大的不同。请谨慎测试。

 

分享到:
评论

相关推荐

    精通正则表达式~~~

    第5章:正则表达式实用技巧.... 185 正则表达式的平衡法则... 186 若干简单的例子... 186 匹配连续行(续前)... 186 匹配IP地址... 187 处理文件名... 190 匹配对称的括号... 193 防备不期望的匹配... 194 ...

    写出高效率的正则表达式技巧总结

    如果所写的正则表达式只是为了满足一两次、几十次的运行,优化与否区别也不太大。但是,如果所写的正则表达式会百万次、千万次地运行,效率就是很大的问题了。  为行文方便,先定义两个概念。 误匹配:指正则表达式...

    [Excel.VBA程序开发自学宝典(第2版)].罗刚君.扫描版.pdf

    《ExcelVBA程序开发自学宝典(第2版)》是VBA入门的经典教材,对VBA的基础理论、语法规则、代码优化、编写思路、开发函数与使用数组等都进行了详尽的理论阐述和案例演示,同时还搭配窗体与控件、正则表达式、字典、...

    Java基础知识点总结.docx

    二十、 正则表达式:其实是用来操作字符串的一些规则★★★☆ 135 二十一、 设计模式★★★★★ 136 设计模式简介 136 单例设计模式:★★★★★ 156 工厂模式★★★★★ 159 抽象工厂模式★★★★★ 163 建造者模式...

    java版飞机大战源码-Resources:收集资源

    java版飞机大战源码 Resources 个人编码资料收集总结仓库,因为很多文章都是存储过才进行整理的,大多数链接为我的印象笔记中存储的笔记链接,笔记中包含原地址链接...正则表达式 持续集成 Curry 富文本 Clean Archite

    2021年MySQL高级教程视频.rar

    24.MySQL高级SQL技巧SQL执行顺序及正则表达式.avi 25.MySQL高级SQL技巧数字函数与字符串函数.avi └26.MySQL高级SQL技巧日期函数与聚合函数.mp4 ├第二天视频 01.MySQL高级今日内容.mp4 02.MySQL高级体系结构.avi 03...

    PHP和MySQL WEB开发(第4版)

    4.9 比较字符串函数和正则表达式函数 4.10 进一步学习 4.11 下一章 第5章 代码重用与函数编写 5.1 代码重用的好处 5.1.1 成本 5.1.2 可靠性 5.1.3 一致性 5.2 使用require()和include()函数 5.2.1 文件扩展名和...

    PHP和MySQL Web开发第4版pdf以及源码

    4.9 比较字符串函数和正则表达式函数 4.10 进一步学习 4.11 下一章 第5章 代码重用与函数编写 5.1 代码重用的好处 5.1.1 成本 5.1.2 可靠性 5.1.3 一致性 5.2 使用require()和include()函数 5.2.1 文件...

    PHP和MySQL Web开发第4版

    4.9 比较字符串函数和正则表达式函数 4.10 进一步学习 4.11 下一章 第5章 代码重用与函数编写 5.1 代码重用的好处 5.1.1 成本 5.1.2 可靠性 5.1.3 一致性 5.2 使用require()和include()函数 5.2.1 文件...

    史上最好传智播客就业班.net培训教程60G 不下会后悔

    .Net精品就业班课程表 : 1、.Net基础加强(10天) 核心技术课程 常用数据结构(List、Dictionary、...项目说明 总结以往所学知识,讲解《传智播客.Net面试、笔试宝典》,介绍简历、笔试、面试等所需的知识和技巧。

    asp.net知识库

    .net中的正则表达式使用高级技巧 (一) C#静态成员和方法的学习小结 C#中结构与类的区别 C#中 const 和 readonly 的区别 利用自定义属性,定义枚举值的详细文本 Web标准和ASP.NET - 第一部分 XHTML介绍 在ASP.NET...

    RED HAT LINUX 6大全

    14.5 优化Samba性能 250 14.6 测试配置 251 14.7 运行Samba服务器 252 14.8 共享访问 252 14.8.1 在Linux客户上使用smbclient 252 14.8.2 在Linux客户上加载共享 253 14.8.3 在Windows客户上加载共享 253 14.9 公用...

Global site tag (gtag.js) - Google Analytics