正则表达式

正则表达式是计算机科学的一个概念,正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。正则表达式通常用来检索、替换那些匹配某个模式的文本。

元字符

所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符。

常用的元字符

代码 说明
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
\B 非单词边界匹配
^ 匹配字符串的开始
$ 匹配字符串的结束
() 标记一个子表达式的开始和结束

字符转义

如果你想查找元字符的话,需要使用 \ 来取消这些字符的特殊含义。比如要查找 . 的话需要使用 \. ,要查找 \ 需要使用 \\

限定符

指定数量的代码。

常用的限定符

代码/语法 说明
* 重复0次或更多次
+ 重复1次或更多次
重复0次或1次
{n} 重复 n 次
{n,} 重复 n 次或更多次
{n,m} 重复 n 到 m 次

范围表达式

用于指定一个字符范围。

比如:
[aeiou] :任何一个元音字母。
[0-9] : 0-9,即一位数字。
[.?!] : 标点符号 . 或者 或者
[a-z0-9A-Z_] : 匹配任意一位数字或字母或者下划线。

分组

可以用小括号来指定 子表达式 (也叫做 分组),然后可以对子表达式进行一些操作。
比如:
(\d{1,3}\.){3}\d{1,3} 是一个简单的 IP 地址匹配表达式,\d{1,3} 匹配1到3位的数字,(\d{1,3}\.){3} 匹配1个数字加一个 .,然后(将表达式)重复3次,最后再加一个1到3位的数字 \d{1,3}

分支条件

指的是有几种规则,如果满足其中任意一种规则都应该当成匹配。具体方式是使用 | 将条件分开。
比如:
0\d{2}-\d{8}|0\d{3}-\d{7} : 匹配以 - 分割的电话号码:一种是3位区号,8位本地号码(010-12345678);一种是4位区号,7位本地号码(0101-1234567)。

零宽断言

用来查找在某些内容(但并不包括这些内容)之前之后的东西,也就是说它们像 \b,^,$ 那样用于指定一个位置,这个位置需要满足一定的条件(即断言)。

零宽度正预测先行断言

(?=exp)
没找到原翻译出处,光是这么几个字真是不好记。可以简单理解为(断言)匹配一个位置,然后匹配出这个位置前的内容。
比如: 用 \b\w+?(?=\sjust) 查找 The things you say just might be true 会匹配出 say,可以理解为就是先用 \sjust 匹配到位置,然后匹配到 just 前的一个单词。

零宽度正回顾后发断言

(?<=exp)
跟上面说的相反,断言自身的位置,然后匹配之后的内容。
比如: 用 (?<=\sjust\s)\b\w+?\b 查找 The things you say just might be true 会匹配出 might,可以理解为就是先用 \sjust\s 匹配到位置,然后匹配到 just 后的一个单词。

负向零宽断言

跟零宽断言正好相反,用来确保某些内容没有出现。

零宽度负预测先行断言

(?!exp)
断言此位置后面不能匹配表达式exp。
比如: 用 \bto\b\s(?!take\s) 查找 I am here to take you to a good life 就只能匹配出第二个 to,就是 to 的后面不能跟 take\s

零宽度负回顾后发断言

(?<!exp>)
断言此位置的前面不能匹配表达式。
比如:
(?<!here\s)\bto\b 查找 I am here to take you to a good life 就只能匹配出第二个 to,就是不要 here\s 后面跟着的 to

贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能的字符。
比如:
a.*b 查找 aabab 的话,会匹配出 aabab,这就叫贪婪匹配。

懒惰

有时候我们想匹配尽可能少的字符,只要在它后面加上一个问号 。这样就意味在匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
比如:
a.*?b 匹配最短的,以 a 开始,以 b 结束的字符串。如果用于 aabab 的话,它会匹配 aab

懒惰限定符

代码 说明
.? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复