正则表达式

正则表达式是一种用于匹配和操作文本的强大工具,它是由一系列字符和特殊字符组成的模式,用于描述要匹配的文本模式


结构

我们来看一个典型的正则表达式,该表达式用于匹配中国大陆身份证号码

/^(?<province>1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[1-3]|6[1-5]|7[1-3]|8[1-2]|9[1-2])[0-9]{4}(?<birthday>19[0-9]{2}|20[0-1][0-9])(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])(?<sequence>[0-9]{3})(?<check>[0-9Xx])$/

正则表达式以/^$/作为定界符,分别表示正则表达式的开始与结束,字符 ^$ 同时使用时,表示精确匹配

形如(?<province>...)(?'province'...)的结构称为命名捕获组,表示将匹配的内容捕获进名为province的组中

1[1-5]|2[1-3]|这表示第一位数字为1时,第二位数字只能为1~5中的值,如果第一位数字为2,则第二位数字的取值范围则为1~3,因此可见|符号用于表达一种逻辑或关系

在第一个命名捕获组结束后,{4}精确数量限定符,表示前面的模式必须恰好重复4次,用于匹配身份证中的市级、县级地址码,该限定符只对前面的[0-9]有效,表示第一个命名捕获组结束后应接4个任意数字

后面生日的部分就很好理解了,这里匹配了1900~2019年间出生的人,还有顺序码,匹配三位数字

最后是校验码,[0-9Xx]表示匹配任意数字和字母Xx


元字符

正则表达式中的元字符是具有特殊含义的字符,它们不表示字面意义,而是用于控制匹配模式

基本元字符

元字符 功能描述 示例
. 匹配**除换行符(\n)**外的任意单个字符 a.b
^ 匹配字符串的开始位置 ^abc
$ 匹配字符串的结束位置 xyz$
\ 1. 使特殊字符变为普通字符 2. 使普通字符获得特殊含义 \d

字符类元字符

元字符 功能描述 示例
[ ] 定义字符集合,匹配其中任意一个字符 [aeiou]
[^ ] 匹配不在方括号中的任意字符 [^0-9]
- 在字符类中表示字符范围 [a-z][0-9A-F]

量词元字符

元字符 功能描述 示例
\* 匹配前面的子表达式零次或多次 ab*c
+ 匹配前面的子表达式一次或多次 ab+c
? 匹配前面的子表达式零次或一次 colou?r
{n} 精确匹配前面的子表达式n次 a{3}
{n,} 匹配前面的子表达式至少n次 a{2,}
{n,m} 匹配前面的子表达式n到m次 a{2,4}

分组和选择元字符

元字符 功能描述 示例
( ) 定义子表达式或捕获组 (ab)+
| 表示逻辑”或”关系 cat|dog

特殊字符类元字符

元字符 功能描述 等价字符类
\d 匹配任意数字 [0-9]
\D 匹配任意非数字 [^0-9]
\w 匹配任意单词字符(字母、数字、下划线) [a-zA-Z0-9_]
\W 匹配任意非单词字符 [^a-zA-Z0-9_]
\s 匹配任意空白字符(空格、制表符、换行符等) [ \t\r\n\f]
\S 匹配任意非空白字符 [^ \t\r\n\f]

边界匹配元字符

元字符 功能描述 示例
\b 匹配单词边界(单词与非单词字符的交界处) \bcat\b
\B 匹配非单词边界 \Bcat\B

\bcat\b 匹配 cat 但不匹配 category\Bcat\B 匹配 scattered中的 cat但不匹配单独的 cat

其他元字符

元字符 功能描述 ASCII值 常见来源
\n 匹配换行符(换行) 0x0A Unix/Linux 换行符
\t 匹配制表符 0x09 键盘 Tab 键
\r 匹配回车符 0x0D 老式 Mac 换行符,Windows 换行符的一部分
\f 匹配换页符 0x0C 打印机换页
\v 匹配垂直制表符 0x0B 垂直制表

修饰符

正则表达式修饰符(也称为模式修饰符或标记)是用于改变正则表达式匹配行为的特殊指令,标记不写在正则表达式里,标记位于表达式之外,格式:/pattern/flags

修饰符 功能描述 示例
i 忽略大小写,使匹配不区分大小写 /abc/i
g 全局匹配,查找所有匹配项而不是第一个就停止 /ab/g
m 多行模式,使 ^$ 匹配每行的开头和结尾 /^abc/m
s 单行模式,使点号 . 匹配包括换行符在内的所有字符 /a.b/s
u Unicode模式,启用完整的Unicode支持 /\p{L}/u
y 粘性匹配,从目标字符串的当前位置开始匹配 /a/y
x 扩展模式,忽略模式中的空白和注释 /a b c/x

断言

断言(Assertion)是正则表达式中用于指定匹配位置的元字符,它们不匹配任何实际字符,而是匹配字符之间的位置

断言类型 正则语法 别称 检查方向 期望条件
正向先行断言 (?=pattern) 正前瞻 向右(向前) 存在 pattern
负向先行断言 (?!pattern) 负前瞻 向右(向前) 不存在 pattern
正向后行断言 (?<=pattern) 正后顾 向左(向后) 存在 pattern
负向后行断言 (?<!pattern) 负后顾 向左(向后) 不存在 pattern

功能特点

零宽度:只检查条件,不消耗字符(不包含在匹配结果中)

非捕获:断言中的 pattern 不会被捕获到分组中

顺序敏感:匹配引擎按顺序检查断言条件


运算符优先级

下表从最高到最低说明了各种正则表达式运算符的优先级顺序

运算符 描述
\ 转义符
(), (?:), (?=), [] 圆括号和方括号(分组和字符类)
*, +, ?, {n}, {n,}, {n,m} 限定符(量词)
^, $, \任何元字符、任何字符 定位点和序列(位置和顺序)
| 替换,逻辑或

分组和引用

在正则表达式中,分组(Grouping)允许我们将多个字符视为一个整体单元

基本语法

使用圆括号 () 来创建分组:(表达式)

例如,(ab)+ 可以匹配 “ab”、”abab”、”ababab” 等,但不能匹配 “a” 或 “b”

分组类型

分组类型 语法 功能描述
捕获分组 (表达式) 捕获匹配内容并分配编号(从1开始)
非捕获分组 (?:表达式) 只分组但不捕获匹配内容
命名分组 (?<name>表达式)(?P<name>表达式) 捕获匹配内容并分配名称

分组引用

引用类型 语法 功能描述
反向引用(表达式内) \数字 在正则表达式内部引用前面捕获分组的内容
命名反向引用(表达式内) \k<name> 在正则表达式内部引用前面命名分组的内容
替换引用(替换操作中) $数字\数字 在替换字符串中引用前面捕获分组的内容