(首发于 2018 年 8 月 7 日)
正则表达式是由普通字符以及特殊字符(称为“元字符”)组成的文字模式,可以作为模板,用来描述在搜索文本时要匹配的一个或多个字符串。
1. 常见元字符
元字符主要作用有:用来匹配字符、用来匹配位置、用来匹配数量和用来匹配模式。常见的元字符如下表所示。
元字符 | 含义 |
---|---|
. | 匹配除换行符以外的任意字符 |
\b | 匹配单词的开始或结束 |
\d | 匹配数字 |
\w | 匹配字母、数字、下划线和汉子 |
\s | 匹配任意空白符,包括空格、制表符、换行符、中午全角空格 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
2. 字符转义
如果需要匹配元字符本身,我们需要用到字符转义来实现,使用 “\” 来取消元字符的特殊含义。
例如,需求是匹配 https://yhw-miracle.win/ 这个网址时,正则表达式可以写成 https://yhw-miracle\.win/。
3. 重复
正则表达式中用于匹配重复的字符串,可以使用限定符描述,简化正则表达式的书写。
限定符 | 含义 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复 n 次 |
{n,} | 重复 n 次或更多次 |
{n,m} | 重复 n 到 m 次 |
4. 字符集合
如果需求是匹配没有预定义元字符的字符集合,例如需求是匹配 a,b,c,d,e 中任意一个字符,可以使用自定义字符集合。正则表达式支持自定义字符集合,用 [] 来实现自定义字符集合,中括号内写要匹配的自定义字符集合。对于上述需求,可以使用 [abcde] 来匹配待定字符串。
中括号内不仅可以写自定义的字符集合,还可以指定自定义字符范围,例如 [0-9] 与 “\d” 是等价的,[a-z0-9A-Z_] 与 “\w” 是等价的(英文情况下)。
5. 分支条件
正则表达式支持多种匹配规则,满足任意一种规则都是匹配成功,这叫作分支条件,用 “|” 把不同匹配规则分隔开即可。
例如匹配 7-11 位 QQ 号,可以利用分支条件。
正则表达式为:[1-9]\d{6} | [1-9]\d{7} | [1-9]\d{9} | [1-9]\d{9} | [1-9]\d{10}
6. 分组
对于有规律的字符串,我们可以将其分组,分组每一组,从而写出可以匹配的正则表达式。
需求:匹配 IP 地址。
分析:IP 地址可以分为四组,以 . 分隔开,每一组数字不能大于 255。
正则表达式:((25[0-5] | 2[0-4]\d | [0-1]\d{2} | [1-9]?\d).){3}(25[0-5] | 2[0-4]\d | [0-1]\d{2} | [1-9]?\d).)
正则表达式中使用小括号指定的表达式为一个分组,默认情况下,每一个分组自动有一个组号,从左到右,以分组的左括号为标志,第一个出现的分组组号为 1,第二个出现是分组组号为 2,以此类推。正则表达式可以利用分组号引用前面组的表达式,这叫做后向引用,简化正则表达式的书写。
对于分组,我们也可以自定义分组名,利用自定义分组名引用相应的分组。语法为:(?\d+) 或 (?”group”\d+),这样就把 “\d+” 的组名定义为 “group” 了。如果要引用这个分组的内容,可以使用 \k 来实现。常见的分组形式如下表所示。
分类 | 语法 | 含义 |
---|---|---|
捕获 | (exp) | 匹配 exp,并捕获文本到自动命名的组里 |
捕获 | (?exp) or (?”name”exp) | 匹配 exp,并捕获文本到名称为 name 的组里 |
捕获 | (?:exp) | 匹配 exp,不捕获匹配的文本,也不给此分组分配组号 |
零宽断言 | (?=exp) | 匹配 exp 前面的位置 |
零宽断言 | (?<=exp) | 匹配 exp 后面的位置 |
零宽断言 | (?!exp) | 匹配后面跟的不是 exp 位置 |
零宽断言 | (?<!exp) | 匹配前面不是 exp 位置 |
注释 | (?#comment) | 提供注释 |
7. 反义
如果需求是匹配除了某一类字符集合之外的字符,这时候可以使用反义来实现。
反义 | 含义 |
---|---|
\W | 匹配任意不是字母、数字、下划线、汉子的字符 |
\S | 匹配任意不是空白符和字符 |
\D | 匹配任意不是非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^a] | 匹配除了 a 之外的任意字符 |
[^abcde] | 匹配除了 a、b、c、d、e 这几个字母之外的任意字符 |
[^(123 | abc)] | 匹配除了 1、2、3 或者 a、b、c 这几个字符之外的任意字符 |
8. 贪婪与懒惰
正则表达式中包含能接受重复的限定符时,通常情况是匹配尽可能多的字符,这是贪婪模式。有时,需求不希望匹配尽可能多的字符,这时可以使用懒惰模式,就是尽可能少的匹配字符,使用 “?” 启用懒惰模式。
懒惰限定符 | 含义 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复 1 次或更多次,但尽可能少重复 |
?? | 重复 0 次或 1 次,但尽可能少重复 |
{n,m}? | 重复 n 到 m 次,但尽可能少重复 |
{n,}? | 重复 n 次以上,但尽可能少重复 |
9. 处理选项
处理选项 | 含义 |
---|---|
忽略大小写 | 匹配时不区分大小写 |
多行模式 | 更改 “^” 和 “$” 的含义,使得它们在任意一行的行首和行尾进行匹配 |
单行模式 | 更改 “.” 的含义,使得它与任意字符匹配,包括换行符 |
忽略空白 | 忽略表达式中非转义空白并启用有 “#” 标记的注释 |
显示捕获 | 仅捕获已被显示命名的分组 |