正则表达式
正则表通常被用来检索、替换那些符合某个模式(规则)的文本
组成
边界符
边界符 | 说明 |
---|---|
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁结束) |
( ) | 标记一个子表达式的开始和结束位置 |
1、 ()
/([1-9])([a-z])/g
匹配 1a2b
-> 1a 2b
圆括号会有一个副作用,使相关的匹配会被缓存,此时可用 ?: 放在第一个选项前来消除这种副作用
- exp1(?=exp2):查找 exp2 前面的 exp1
- (?<=exp2)exp1:查找 exp2 后面的 exp1
- exp1(?!exp2):查找后面不是 exp2 的 exp1
- (?
字符类
范围
一系列字符可供选择,只要匹配其中一个就可以了
- [ABC] 被匹配字符串中所有的 A B C 字母
- [^ABC] 除了A B C 字母的其他字符
- [A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母
- | 或,如 ab|bc 代表 ab 或 bc
量词
量词 | 说明 |
---|---|
* | 重复0次或更多次, 要匹配 * 字符,使用 \* |
+ | 重复1次或更多次, 要匹配 + 字符,使用 \+ |
? | 重复0次或1次, 要匹配 ? 字符,使用 ? |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
- 贪婪模式:正则中量词默认是贪婪匹配,用 a* 去匹配 aaabb 只会匹配 aaa
- 非贪婪模式:用 a*? 去匹配 aaabb 就只会匹配到单个的 a
- 独占模式:贪婪和非贪婪匹配都可能会进行回溯,独占模式也是进行贪婪匹配,但不进行回溯
修饰符
- i ignore - 不区分大小写
- g global - 全局匹配
- m multi line - 多行匹配,使边界字符 ^ 和 $ 能匹配每一行的开头和结尾
- s 正常情况下特殊字符圆点 . 会匹配除了换行符的任意字符,用了 s 模式后,特殊字符圆点 . 中也会把换行符匹配上
修饰符除了可以全局指定外,也可以在正则中对某一个分组来指定,如 (?i)(abc)ABC
匹配 ABCABC
预定义类
预定类 | 说明 |
---|---|
\cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符 |
\f | 匹配一个换页符 |
\n | 换行符 |
\r | 回车符 |
\t | 匹配一个制表符 |
\v | 匹配一个垂直制表符 |
\d | 匹配0-9之间的任一数字, 相当于[0-9] |
\D | 匹配所有0-9以外的字符,相当于[^0-9] |
\w | 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_ ] |
\W | 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_ ] |
\s | 匹配空格(包括换行符、制表符、空格符等),相等 于[ \tlr\n\v\f] |
\S | 匹配非空格的字符,相当于[^ \tlr\n\v\f] |
\b | 匹配一个单词边界,即字与空格间的位置 |
\B | 非单词边界匹配 |
运算符的优先级
从高到低:
- \
- `(), (?:), (?=), []`
- ^, $, \任何元字符、任何字符
- |
正则流派
- POSIX 特征是不支持 \d
- BRE
- ERE
- PCRE 大部分编程语言使用的标准,特征是支持 \d
正则性能
- 提前编译:正则表达式都是通过被编译成自动机来进行字符串匹配的,所以使用编译好的正则表达式会比使用未编译的正则表达式更快
- 尽量准确表示匹配的范围,避免过于宽泛的匹配范围
- 提取出公共的部分,如 (abcd|abxy) 优化成 ab(cd|xy)
- 出现可能性大的放左边,由于正则是从左到右看的,把出现概率大的放左边,域名中 .com 的使用是比 .net 多的,所以我们可以写成`\.(?:com|net)\b`,而不是`\.(?:net|com)\b`。
- 只在必要时才使用子组,在正则中,括号可以用于归组,但如果某部分后续不会再用到,就不需要保存成子组。如果保存成子组,正则引擎必须做一些额外工作来保存匹配到的内容
- 警惕嵌套的子组重复,如果一个组里面包含重复,接着这个组整体也可以重复,比如 `(.*)*` 这个正则,匹配的次数会呈指数级增长
- 避免不同分支重复匹配