关于正则表达式

正则表达式,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} \d{4}-\d{7}`
`(([1-9]?\d 1\d{2}

正则表达式合集

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

参考链接

https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md