正则表达式语法&优化

简单备忘正则表达式的原理、基本使用方法,和一些常见的优化方法。目的看懂网上摘抄的正则表达式,避免使用效率过低的正则。

原理

正则文法分为确定型有限状态自动机(DFA)和非确定型优先状态自动机(NFA),两种正则匹配算法能力相同,效率有区别。

  • NFA 表达式主导
    从表达式的第一部分开始,每次检查一部分,同时检查当前文本是否匹配,如果是,则继续表达式的下一部分,如此继续,直到表达式的所有部分都能匹配。整个过程,控制权在表达式的元素之间转换,因此被称为表达式主导"。
  • DFA 文本主导
    DFA在读入一个文本的时候,会记录当前有效的所有匹配的表达式位置。被扫描的字符串控制了引擎执行过程。

构造DFA会消耗更多的时间和内存。但是DFA构造好了以后执行效率更理想。NFA在匹配的过程中,存在大量的分支和回溯。Java、JavaScript等语言使用NFA,MySQL使用DFA。

语法

  1. 元字符
字符 说明
. 除换行符外所有字符
\w 字母、数字、下划线、汉字
\d 数字
\s 空白符
\b 匹配单词
^ 字符串开始
$ 字符串尾
  1. 量词
语法 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
  1. 分组,反向引用
  • 使用 () 进行分组匹配
  • 使用 \1\2 按顺序反向引用分组内容
  • 使用 (?<name>exp) 捕获到名称为name的分组
  • 使用 (?:exp) 匹配exp,不捕获匹配分组,也不分配组号
  1. 匹配量词
    在正则表达式次数限定符后增加该量词,可以指定匹配规则。
名称 方法 说明
Greedy:贪婪 默认 匹配最长。在贪婪量词模式下,正则表达式会尽可能长地去匹配符合规则的字符串,且会回溯。
Reluctant :非贪婪,懒惰 ? 匹配最短。在非贪婪量词模式下,正则表达式会匹配尽可能短的字符串。
Possessive :独占 + 同贪婪一样匹配最长。不过在独占量词模式下,正则表达式尽可能长地去匹配字符串,一旦匹配不成功就会结束匹配而不会回溯。
  1. 其他
  • 使用 \ 进行转义
  • 使用 | 表示或
  • 使用 [] 表示区间条件

优化

  1. 合理使用括号
    当要捕获组的时候,使用非捕获型括号(?:),这是写策略正则最常用的优化方法,因为使用(?:)可以匹配想要的内容,但不捕获到组里,可以节省资源,提高效率。
  2. 尽量使用非贪婪模式
    尽量使用非贪婪模式,因为贪婪模式情况下,容易造成回溯。
  3. 使用字符组代替分支条件
    使用[a-d]表示a~d之间的字母,而不是使用(a|b|c|d)
  4. 谨慎用点号元字符,尽可能不用星号和加号这样的任意量词
    例子: 要匹配 <12345>,其中<>中间是1-5位的数字
    正常写法: <\d*>
    优化写法: <\d{1,5}>
  5. 使用占有优先量词和固化分组
    占有优先量词?+ *+ ++ {m,n}+
    占有优先量词与匹配优先量词很相似,只是它们从来不会交还已经匹配的字符。
    固化分组(?>exp)
    固化分组的内容与正常的匹配并无区别,只是当匹配完括号中的内容后,括号中的备用状态会全部舍去。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 匹配基础 对于正则表达式,有两条普适原则: 优先选择最左端的匹配结果; 标准的匹配量词(*、+、?和{min, m...
    戴小白阅读 4,199评论 1 6
  • 背景 最近公司规范出来后,关于字符串不提倡用 “ + ” 进行拼接,于是自己写了个function,利用正则...
    iammei阅读 3,942评论 0 1
  • 原文参考自: //www.greatytc.com/p/681d3e07fb0f 一、原理概论 1、正则...
    Rui哥阅读 576评论 0 2
  • 正则表达式概念源于 《神经网事件的表示法》论文中。 正则表达式就是用某种模式去匹配一类字符串的一种公式。 正则表达...
    单板小智阅读 799评论 0 1
  • 正则表达式到底是什么东西?字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等...
    狮子挽歌阅读 2,180评论 0 9