关于正则表达式

正则表达式,regular expression,简写为 regex

一组有一些相同特征的字符串可以用正则表达式简洁地表示出来。也就是说,正则表达式是用来简洁地表示一组字符串的表达式。

正则表达式的作用:

  • 表达一组字符串的特征。
  • 同时查找或替换一组字符串。
  • 字符串匹配。

元字符

元字符一览表

元字符 描述
. 匹配除换行符外的任意单个字符
[] 字符集。匹配方括号内的任意一个字符
[^] 否定字符集。匹配除了方括号里字符外的任意字符
{n,m} 匹配前面的字符 n 到 m 次
* 匹配指定表达式 >=0 次
+ 匹配指定表达式 >= 1次
? 匹配指定表达式 0 次 或 1 次
(xyz) 匹配与 xyz 完全相等的字符串
| 或运算符,匹配符号前或后的字符
\\ 转义字符
^ 检查模式串是否在主串的开头
$ 检查模式串是否在主串的结尾

点运算符 .

. 可以匹配除换行符以外的任意字符。

如果用 \. 转义,或将 . 写在 [] 内,. 会变成普通字符,只能匹配英文句号

字符集 [] 和否定字符集 [^]

字符集也叫做字符类,方括号用来指定一个字符集。

字符集有两种写法:[aeiou][a-z],后一种写法表示从 a 到 z 的任意字符。

在方括号开始处加上 ^ 元字符,该字符集会变为否定字符集,如:[^aeiou]

重复次数

  1. {n,m}:匹配前面的字符 n 到 m 次。如果省略 m,表示匹配前面的字符 n 到无穷次,如:{0,};如果逗号也省略掉则表示重复固定的次数,如:{3} 表示重复三次。
  2. * 号:匹配指定表达式 >=0 次,等价于 {0,}
  3. + 号:匹配指定表达式 >=1 次,等价于 {1,}
  4. ? 号:匹配指定表达式 0 次或 1 次,等价于 {0,1}

(...) 特征标群

特征标群是一组写在 () 中的子模式。

使用特征标群将字符组合起来以后,元字符可以作用在整个特征标群上。如:(abc){5} 会匹配 abc 重复 5 次。

或运算符 |

与其他元字符不同的是,其他元字符往往以一个字符为单位,而或运算符以一个字符串为单位,直到字符串结束或遇到 ()

如:abcd|efgh 匹配 abcdefgh

我们经常使用 () 来限制或运算符的作用范围,如:(a|b)cd 匹配 acdbcd

转义符号 \

使用 \ 可以将元字符转义为普通字符,或将某些普通字符转义为简写字符集。

锚点

在正则表达式中,想要匹配指定开头或结尾的字符串就要使用到锚点。^ 指定开头,$ 指定结尾。

例如 ^(T|t)he 只能匹配字符串开头的 The 或 the,(T|t)he$ 只能匹配字符串结尾的 The 或 the。

简写字符集

正则表达式提供了一些常用的字符集简写,如下:

简写 描述
. 匹配除换行符外的所有字符
\\d 匹配数字。等同于 [0-9]
\\D 匹配非数字。等同于 [^\\d]
\\w 匹配所有字母数字。等同于 [a-zA-Z0-9_]
\\W 匹配所有非字母数字,即符号。等同于 [^\\w]
\\s 匹配所有空白字符。等同于 [\\t\\n\\f\\r\\p{Z}]
\\S 匹配所有非空白字符。等同于 [^\\s]
\\n 匹配一个换行符
\\r 匹配一个回车符
\\p 匹配 CRLF(等同于 \\r\\n
),即 windows 下的行终止符
\\t 匹配一个制表符
\\v 匹配一个垂直制表符
\\f 匹配一个换页符

零宽度断言(前后预查)

断言的作用与种类

先行断言用于判断所匹配的格式是否在另一个确定的格式之前,匹配结果不包含该确定格式;相对的,后发断言用于判断所匹配的格式是否在另一个确定的格式之后。

例如,如果想要获得所有跟在 $ 符号后的数字,可以使用正后发断言 (?<=\$)[0-9\.]*。这个表达式匹配 $ 开头,之后跟着 0,1,2,3,4,5,6,7,8,9,.,这些字符可以出现大于等于 0 次。

零宽度断言有如下几种:

符号 描述
?= 正先行断言 - 存在
?! 负先行断言 - 排除
?<= 正后发断言 - 存在
?<! 负后发断言 - 排除

正先行断言

?=... 正先行断言,表示第一部分表达式之后必须跟着 ?=...定义的表达式。

返回结果只包含满足匹配条件的第一部分表达式。定义一个正先行断言要使用 ()。在括号内部使用一个问号和等号:(?=...)

正先行断言的内容写在括号中的等号后面。例如,表达式 (T|t)he(?=\sfat) 匹配 Thethe,在括号中又定义了正先行断言 (?=\sfat),即 Thethe 后面紧跟着 (空格)fat

(T|t)he(?=\sfat) —> The fat cat sat on the mat.

负先行断言

负先行断言 ?! 用于筛选所有匹配结果,筛选条件为 其后不跟随着断言中定义的格式。负先行断言定义和正先行断言一样,区别就是 = 替换成 ! 也就是 (?!...)

表达式 (T|t)he(?!\sfat) 匹配 Thethe,且其后不跟着 (空格)fat

(T|t)he(?!\sfat) —> The fat cat sat on the mat.

正后发断言

正后发断言记作(?<=...),用于筛选所有匹配结果,筛选条件为其前跟随着断言中定义的格式。例如,表达式 (?<=(T|t)he\s)(fat|mat) 匹配 fatmat,且其前跟着 Thethe

(?<=(T|t)he\s)(fat|mat) —> The fat cat sat on the mat.

负后发断言

负后发断言记作 (?<!...),用于筛选所有匹配结果,筛选条件为其前不跟随着断言中定义的格式。例如,表达式 (?<!(T|t)he\s)(cat) 匹配 cat,且其前不跟着 Thethe

(?<!(T|t)he\s)(cat) —> The cat sat on cat.

贪婪匹配与惰性匹配

正则表达式默认采用贪婪匹配模式,在该模式下意味着会匹配尽可能长的子串,而惰性匹配则是匹配尽可能短的子串。

如对于字符串 <div>some words</div> 来说,<.*> 会匹配整个字符串,因为默认贪婪匹配。

在表示重复次数的元字符后面加上一个 ? 会启用惰性匹配模式,如:

  1. ? —> ??
  2. * —> *?
  3. + —> +?
  4. {1,} —> {1,}?

所以,对于上面的字符串,<.*?> 的匹配结果是 <div>

标志

常用正则表达式

表达式 作用
^[A-Za-z]+$ 开头和结尾字符完全匹配,中间为任意个英文字母
^[A-Za-z0-9]+$ 开头和结尾字符完全匹配,中间为任意个英文字母或数字
^-?\\d+$ 开头和结尾字符完全匹配,表示一个整数
^[0-9]*[1-9][0-9]*$ 开头和结尾字符完全匹配,表示一个正整数
[1-9]\\d{5} 中国境内的邮政编码
[\\u4e00-\\u9fa5] 匹配中文字符(UTF-8 编码)
\\d{3}-\\d{8}&#124;\\d{4}-\\d{7} 国内电话号码,如:010-68913536
(([1-9]?\\d&#124;1\\d{2}&#124;2[0-4]\\d&#124;25[0-5])\\.){3}([1-9]?\\d&#124;1\\d{2}&#124;2[0-4]\\d&#124;25[0-5]) 匹配 ip 地址

正则表达式合集:

一组匹配中国大陆手机号码的正则表达式:

Reference