跳转至

正则表达式

约 1237 个字 预计阅读时间 4 分钟

正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

———— 维基百科

Abstract

正则表达式用途广泛,而且功能强大又好用。可以说既简单又繁琐,但是用起来很爽

一些工具:

语法

普通字符

所有不是元字符的字符都可以直接写出来用来匹配,比如大小写字母、数字、符号等

有语法意义的字符需要使用 \ 转义,比如 \( \) \[ \] \. 分别匹配 ()[]. 这五个字符

语法 描述
[...] 匹配任意在 ... 中的字符,如 [ABC] 匹配所有 A B C 字符
[^...] 匹配任意不在 ... 中的字符,如 [^ABC] 匹配除了 A B C 外的所有单个字符
[x-y] 按照顺序匹配从 xy 到所有字符,如 [a-z] 匹配所有小写字母,[A-E] 匹配 A 到 E 这五个字符|
. 匹配任意除了换行符以外的字符
\w 匹配字母数字下划线,相当于 [a-zA-Z0-9_]
x|y 匹配 xy,优先级最低,如 a|bcd 匹配 a 或 bcd

非打印字符

语法 描述
\cx 匹配由 x 指明的控制字符,x 必须属于 [a-zA-Z],否则 \c 直接视为 c,如 \cM 匹配 Ctrl-M 即回车符
\f 匹配一个换页符,相当于 \x0c \cL
\n 匹配一个换行符,相当于 \x0a \cJ
\r 匹配一个回车符,相当于 \x0d \cM
\t 匹配一个制表符,相当于 \x09 \cI
\v 匹配一个垂直制表符,相当于 \x0b \cK
\s 匹配任何空白字符,相当于 [ \f\n\r\t\v],unicode 下也会匹配全角空格符
\S 匹配任何非空白符,相当于 [^ \f\n\r\t\v]

限定符

用来指定一个子表达式出现了多少次

语法 描述
{n} 前一个子表达式匹配准确的 n 次,如 o{2} 匹配两个连续的 o
{n,} 前一个子表达式匹配至少 n 次,如 o{2,} 可以匹配 goooood 中的所有 o,但不匹配 god 中的 o
{n,m} 前一个子表达式匹配至少 n 次,至多 m 次
* 前一个子表达式匹配 0 次或多次,相当于 {0,}
+ 前一个子表达式匹配 1 次或多次,相当于 {1,}
? 前一个子表达式可有可无(匹配 0 次或 1 次),相当于 {0,1}

贪婪

* 和 + 的匹配都是贪婪的,即尽可能匹配更多的字符,而在它们后面加上 ? 就可以非贪婪(即最小匹配)

  • <.*> 会匹配整个 <h1>header</h1> 字符串
  • <.*?> 只会匹配其中的 <h1></h1>

定位符

只匹配位置,没有字符与之对应

语法 描述
^ 匹配字符串开头,如果是多行模式,则新的一行也算新的字符串
$ 匹配字符串结尾,多行模式同理看成多个字符串
\b 匹配单词边界,即字符与空格中间的位置
\B 匹配非单词边界

定位符只能单独使用,不能附加限制符指定个数

分组

用 () 可以指定匹配一个组,使用 () 可以指定不同选项,每一项间用 | 分隔

同时 () 也是捕获分组,即括号内匹配的内容会被缓存,如果要避免这种,需要使用 (?:) 非捕获元来进行匹配

反向引用

被缓存的捕获分组可以直接使用 \n 再次引用,其中 n 是 1 到 2 位的十进制数
捕获分组的编号从 1 开始,最多 99 个,\1 即表示和第一个圆括号中匹配的结果相同的部分

如 (abc|def)\1 匹配 abcabc、defdef 但不匹配 abcdef、defabc

先行断言和后行断言

正则表达式有先行断言(lookahead)和后行断言(lookbehind),分为四种形式:

语法 名称
(?=pattern) 零宽正向先行断言
zero-width positive lookahead assertion
(?!pattern) 零宽负向先行断言
zero-width negative lookahead assertion
(?<=pattern)
零宽正向后行断言
zero-width positive lookbehind assertion
(?<!pattern) 零宽负向后行断言
zero-width negative lookbehind assertion

和定位符类似,它只匹配位置,不匹配内容,所以叫做零宽(zero-width),这些位置的规则是:

  • (?=pattern):匹配后面可以匹配 pattern 的位置
  • (?!pattern):匹配后面无法匹配 pattern 的位置
  • (?<=pattern):匹配前面可以匹配 pattern 的位置
  • (?<!pattern):匹配前面无法匹配 pattern 的位置

修饰符

修饰符不属于表达式的内容,但是指定了匹配的规则,js 中的正则写法为 /pattern/flags
其中 flags 就是修饰符

修饰符 名称 含义
i ignore 忽略大小写
g global 全局匹配,查找所有匹配项
m multi-line 多行匹配,使 ^$ 匹配每行的开头和结尾
s single-line 单行匹配,只视为一个字符串,. 也可以匹配换行符

不同语言中写法和种类不同

优先级

正则表达式也有优先级,同一优先级则从左向右运算,不同优先级则从高到低。从高到低:

  • 转义符 \
  • 括号符 (...) (?:...) (?=...) (?!...) (?<=...) (?<!...) [...] [^...]
  • 限定符 * + ? {n} {n,} {n,m}
  • 定位符 ^ $
  • 字符
  • |