1. 语法
正则表达式是一种用于匹配和操作文本的强大工具,可以在文本中查找、替换、提取和验证特定的模式。
正则表达式是由普通字符(例如字符 a )以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。
1.1 普通字符
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
字面值字符:
字母、数字、空格等
非打印类字符:
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f 匹配一个换页符
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符
\v 匹配一个垂直制表符
1.2 特殊字符(元字符)
.
:匹配任意字符(除了换行符)。
\
:转义字符,用于匹配特殊字符本身。
|
:用于指定多个模式的选择。
\d 匹配一个数字字符
\D 匹配一个非数字字符
\w 匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
\W 匹配非字母、数字、下划线。等价于 [^A-Za-z0-9_]
\s 匹配任何空白字符,包括空格、制表符、换页等。等价于 [ \f\n\r\t\v]
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
[\s\S] 匹配所有
字符类:
[A-Z] [a-z] [0-9] [^abc]
限定符(量词):
*
:匹配前面的模式零次或多次。
+
:匹配前面的模式一次或多次。
?
:匹配前面的模式零次或一次。
{n}
:匹配前面的模式恰好 n 次。
{n,}
:匹配前面的模式至少 n 次。
{n,m}
:匹配前面的模式至少 n 次且不超过 m 次。
注意:
上述6种限定符 默认的匹配规则都是贪婪的,会尽可能多的匹配字符串。只要在它们的后面加上一个 ? 就可以变为非贪婪匹配模式,尽可能少的匹配字符串。
/* <h1>正则表达式学习笔记<h1> */
/<.*>/ //匹配所有:<h1>正则表达式学习笔记<h1>
/<.*?>/ //匹配最小: <h1>
定位符(边界匹配):
^
:匹配字符串的开头。
$
:匹配字符串的结尾。
\b
:匹配单词边界,即字与空格间的位置。
\B
:匹配非单词边界。
注意:
不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。
\b 字符的位置是非常重要的。如果它位于要匹配的字符串的开始,它在单词的开始处查找匹配项;如果它位于字符串的结尾,它在单词的结尾处查找匹配项。
// Chapter aptitude
/\bCha/ /ter\b/ // Chapter满足这两个表达式。\b匹配单词边界
/\Bapt/ //Chapter满足该表达式,但aptitude不满足,\B匹配非单词边界
选择(分组和捕获):
用圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔。
()表示捕获分组,() 会把每个分组里的匹配的值保存起来,多个匹配值可以通过数字 n 来查看(n 是一个数字,表示第 n 个捕获组的内容)。
/* 20231101regex2156notes4789 */
/([0-9])([a-z]+)/g //匹配到两段: 1regex 6notes
注意:
用圆括号会有一个副作用,使相关的匹配会被缓存,此时可用 ?: 放在第一个选项前来消除这种副作用。其中 ?: 是非捕获元之一,还有两个非捕获元是 ?= 和 ?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
exp1(?=exp2):查找 exp2 前面的 exp1
(?<=exp2)exp1:查找 exp2 后面的 exp1
exp1(?!exp2):查找后面不是 exp2 的 exp1
(?<!exp2)exp1:查找前面不是 exp2 的 exp1
其他特殊字符:
字符 | 描述 |
\xn | 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。 |
\num | 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 |
\nml | 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 |
\nu | 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。 |
1.3 反向引用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
可以使用非捕获元字符 ?:、?= 或 ?! 来重写捕获,忽略对相关匹配的保存。
反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词的匹配项的能力。
2. 修饰符
标记也称为修饰符,正则表达式的标记用于指定额外的匹配策略。标记不写在正则表达式里,标记位于表达式之外,格式如下:
/pattern/flags
常用修饰符:
修饰符 | 含义 | 描述 |
i | ignore 不区分大小写 | 匹配不区分大小写 |
g | global 全局匹配 | 查找所有的匹配项 |
m | multi line 多行匹配 | 使边界字符 ^ 和 $ 匹配每一行的开头和结尾,是多行,而不是整个字符串的开头和结尾。 |
s | 特殊字符 . 中包含换行符 \n | 默认情况下 . 是匹配除换行符以外的所有字符,加s则也匹配换行符 |
3. 运算符优先级
正则表达式从左到右进行计算,并遵循优先级顺序。下表为运算符优先级由高到低的顺序:
运算符 | 描述 |
\ | 转义符 |
(), (?:), (?=), [] | 圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m} | 限定符 |
^, $, \任何元字符, 任何字符 | 定位点和序列(即:位置和顺序) |
| | 替换,"或"操作 字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。 |
4. 匹配规则
基本模式匹配:
a ^C+
字符簇:
[a-z] [^0-9]$
确定重复出现:
d{2,} ^z$