正则表达式

(首发于 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. 处理选项

处理选项 含义
忽略大小写 匹配时不区分大小写
多行模式 更改 “^” 和 “$” 的含义,使得它们在任意一行的行首和行尾进行匹配
单行模式 更改 “.” 的含义,使得它与任意字符匹配,包括换行符
忽略空白 忽略表达式中非转义空白并启用有 “#” 标记的注释
显示捕获 仅捕获已被显示命名的分组

相关文章

正则替换html代码中img标签的src值在开发富文本信息在移动端...
正则表达式
AWK是一种处理文本文件的语言,是一个强大的文件分析工具。它...
正则表达式是特殊的字符序列,利用事先定义好的特定字符以及...
Python界一名小学生,热心分享编程学习。
收集整理每周优质开发者内容,包括、、等方面。每周五定期发...