正则表达式优化

正则表达式优化
——《精通正则表达式》总结

[TOC]

第4章:表达式的匹配原理

引擎

DFA (Deterministic Finite Automaton 确定有穷自动机):
常见的只有MySQL,文本主导,不支持反向引用和捕获括号,但快

传统型 NFA(Non-非):
大多数语言,表达式主导,编译快,内存少,写法不同有性能差异

标准 POSIX NFA:
leftmost-longest,尝试所有确保最长
golang leftmost-first和leftmost-first都支持

混合:Tcl 等

规则

最左优先,尽可能多(匹配优先)

回溯

NFA 有两个可能时会根据 匹配优先* 还是 忽略优先*?
走其中一个分支,并保存备用状态
如果不成功再回溯尝试另一个分支

第5章:正则表达式实用技巧

(多选|分支)排序可能影响匹配结果

第6章:打造高效正则表达式

减少测试和回溯

  • 如果顺序不影响结果时更多匹配的放前面
  1. 编译
  2. 传动(从第1个字符开始,从第2个字符开始...)
  3. 检测(相连 量词{m,n}+* (捕获))
  4. 成功/->2.传动
  5. 失败

常见措施

编译优化

  • 缓存

传动优化

  • 锚点(行始^ \A 起始\G 行末$ \Z \z)
  • 隐式锚点(.* .+开始)
  • 开始字符====={4}快100倍
  • 内嵌字符(Boyer-Moore字符串检索算法后前移, 需要前面固定个数)
  • 长度小于时不运行

正则优化

  • 连接当做整体
  • .*特殊优化比(?:.)*快(Java 10% Python 50倍)
  • 消除没必要的括号
  • 消除没必要的[字符组]
  • 忽略优先量词*?(尽可能少)通常比匹配优先量词慢
  • 限制回溯,避免括号内外都是量词
  • 避免指数级(超线性)匹配
  • 使用占有优先量词(+不会回溯)减少状态
  • \d{4}量词优化比\d\d\d\d快(Java 几倍 Python 20%)
  • 引擎识别捕获括号是否需要

诀窍

  • xx*x+能适应的优化更多

  • 手工模拟优化

  • (000|999)$比关闭结束锚点优化的(?:000|999)$快(Perl 几千倍)

  • 避免重新编译,Perl避免用变量插值

  • 使用(?:非捕获型括号)

  • 不要滥用括号,如上面的.*(?:.)*

  • 不要滥用字符组,[.]应该用\.

  • 不区分大小写效率低已经修正

  • 使用起始锚点.*开头的前面加^\A

  • 从量词中提取: xx*替代x*-----{0,2}替代-{5,7}

  • 提取开头: th(is|at)替代(this|that)

  • 将锚点独立出来: ^(?:abc|123)替代^abc|^123^(abc)替代(^abc)

  • 末尾独立出$

  • 接近开头忽略优先*?,接近结尾匹配优先

  • 拆分成多个正则

  • 使用(?>固化分组)和占有优先量词*+

  • 最可能匹配的分支放前面(POSIX 会全部尝试取最长就不需要)

  • 结尾部分分散到各个部分(有些系统不需要如Perl的$)

消除循环

"(\\.|[^\\"]+)*"

优化为:
"[^\\"]*(\\.[^\\"]*)*"

公式:
opening normal* (special normal*) closing
左 常规*(特殊 常规*)* 右
  1. 常规和特殊的开头不能重合
  2. 特殊部分必须匹配至少一个字符
  3. 特殊部分必须是固化的

方法2:[^\\"]匹配更多,如果是转义,后面继续,结果一样

方法3:匹配主机名

[a-z]+(\.[a-z]+)*

使用占有优先量词

"([^\\"]++|\\.)*+"

使用固化分组

"(?>(?>[^\\"]+|\\.)*)"
\G(?:^|,)(?:((?>[^"]*)(?>""[^"]*)*)|([^",]*))

消除注释

/\*.*?\*/
/\*([^*]|\*+[^/*])*\*+/

消除循环
/\*[^*]*\*+(?:[^/*][^*]*\*+)*/

流畅运转

块注释=/\*[^*]*\*+(?:[^/*][^*]*\*+)*/
行注释=//[^\n]*
双引号="[^\\"]*(?:\\.[^\\"]*)*"
单引号='[^\\']*(?:\\.[^\\']*)*'
(双引号|单引号)|块注释|行注释
替换为
$1

优化为:
开头集=[^"'/]
(双引号|单引号|开头集+)|块注释|行注释

优化为:
(开头集+|双引号|单引号)|块注释|行注释

优化为:
(开头集+|双引号 开头集*|单引号 开头集*)|块注释|行注释

([^"'/]+|
"[^\\"]*(?:\\.[^\\"]*)*"[^"'/]*|
'[^'\\]*(?:\\.[^'\\]*)*'[^"'/]*
)|
/\*[^*]*\*+(?:[^/*][^*]*\*+)*/|
//[^\n]*
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 从匹配中返回值 Match 对象 成功的匹配总是返回一个 Match 对象, 这个对象通常也被放进 $/ 中, (...
    焉知非鱼阅读 1,775评论 0 1
  • 前言 上一篇文章我们学习了正则表达式原理,这次我们学习下怎么写正则表达式。这里,我们不会学习正则表达式的各种符号,...
    张大川大川阅读 1,465评论 0 3
  • 正则表达式是匹配模式,匹配字符或者匹配位置。 一、字符匹配 1.两种模糊匹配 1.1 横向模糊匹配 一个正则可匹配...
    菜菜的小阿允阅读 1,628评论 0 0
  • 一、正则表达式的概念 正则表达式(英语:Regular Expression,在代码中常简写为regex)。正则表...
    圣贤与无赖阅读 881评论 0 3
  • 周一中午业务例会,因为刚吃过午饭,天气也比较闷热,老师们不像以前那样有精神,赵玉辉校长布置教学工作时说:“...
    21719a686a84阅读 159评论 0 0