参考
1.什么是正则表达式?
正则表达式(Regular Expression,简称 Regex 或 RegExp)是一种用来匹配字符串中字符组合的模式。
简单来说就是一种匹配内容的模板。
2.正则表达式的作用
-
查找:在文本中找到特定模式的内容
-
替换:将符合某种模式的文本替换为其他内容
-
验证:检查输入的数据是否符合预期格式
-
提取:从复杂文本中提取需要的信息
3.正则表达式的模式
-
字面值字符:例如字母、数字、空格等,可以直接匹配它们自身。
-
特殊字符:例如点号
.、星号*、加号+、问号?等,它们具有特殊的含义和功能。 -
字符类:用方括号
[ ]包围的字符集合,用于匹配方括号内的任意一个字符。 -
元字符:例如
\d、\w、\s等,用于匹配特定类型的字符,如数字、字母、空白字符等。 -
量词:例如
{n}、{n,}、{n,m}等,用于指定匹配的次数或范围。 -
边界符号:例如
^、$、\b、\B等,用于匹配字符串的开头、结尾或单词边界位置。
4.正则表达式元字符和特性
字符匹配
-
普通字符:普通字符按照字面意义进行匹配,例如匹配字母 "a" 将匹配到文本中的 "a" 字符。
-
元字符:元字符具有特殊的含义,例如
\d匹配任意数字字符,\w匹配任意字母数字字符,.匹配任意字符(除了换行符)等。
基本元字符
. (点号)
-
匹配除换行符(
\n)外的任意单个字符示例:
a.b匹配 "aab", "a1b", "a b" 等
^ (脱字符)
-
匹配字符串的开始位置
-
示例:
^abc匹配以 "abc" 开头的字符串
$ (美元符)
-
匹配字符串的结束位置
-
示例:
xyz$匹配以 "xyz" 结尾的字符串
\ (反斜杠)
-
转义字符,使后面的字符失去特殊含义
-
示例:
\.匹配实际的点号而不是任意字符
量词
-
*:匹配前面的模式零次或多次。 -
+:匹配前面的模式一次或多次。 -
?:匹配前面的模式零次或一次。 -
{n}:匹配前面的模式恰好 n 次。 -
{n,}:匹配前面的模式至少 n 次。 -
{n,m}:匹配前面的模式至少 n 次且不超过 m 次。
字符类
-
[ ]:匹配括号内的任意一个字符。例如,[abc]匹配字符 "a"、"b" 或 "c"。 -
[^ ]:匹配除了括号内的字符以外的任意一个字符。例如,[^abc]匹配除了字符 "a"、"b" 或 "c" 以外的任意字符。 -
[A-Z]:表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母。
边界匹配
-
^:匹配字符串的开头。 -
$:匹配字符串的结尾。 -
\b:匹配单词边界。 -
\B:匹配非单词边界。
分组和选择元字符
() (圆括号)
-
定义子表达式或捕获组
-
示例:
(ab)+匹配 "ab", "abab" 等
| (竖线)
-
表示"或"关系
-
示例:
cat|dog匹配 "cat" 或 "dog"
特殊字符
\d
-
匹配任意数字,等价于
[0-9]
\D
-
匹配任意非数字,等价于
[^0-9]
\w
-
匹配任意单词字符(字母、数字、下划线),等价于
[a-zA-Z0-9_]
\W
-
匹配任意非单词字符,等价于
[^a-zA-Z0-9_]
\s
-
匹配任意空白字符(空格、制表符、换行符等)
\S
-
匹配任意非空白字符
非打印符
| 字符 | 描述 |
|---|---|
| \cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。 |
| \f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
| \n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
| \r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。 |
| \S | 匹配任何非空白字符。等价于 \f\n\r\t\v。 |
| \t | 匹配一个制表符。等价于 \x09 和 \cI。 |
| \v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
5.常用修饰符
1. i (ignore case) - 忽略大小写
-
使匹配不区分大小写
-
示例:
/abc/i可以匹配 "abc", "Abc", "ABC" 等 -
支持语言:几乎所有正则表达式实现(JavaScript、PHP、Python等)
2. g (global) - 全局匹配
-
查找所有匹配项,而不是在第一个匹配后停止
-
示例:在字符串 "ababab" 中,
/ab/g会匹配所有三个 "ab" -
支持语言:JavaScript、PHP等
3. m (multiline) - 多行模式
-
改变
^和$的行为,使其匹配每行的开头和结尾,而不仅是整个字符串的开头和结尾 -
示例:在多行字符串中,
/^abc/m会匹配每行开头的 "abc" -
支持语言:JavaScript、PHP、Python、Perl等
4. s (single line/dotall) - 单行模式
-
使点号
.匹配包括换行符在内的所有字符 -
在JavaScript中称为"dotall"模式,使用
/s修饰符 -
示例:
/a.b/s可以匹配 "a\nb" -
支持语言:PHP、Perl、Python(作为
re.DOTALL)、JavaScript(ES2018+)
5. u (unicode) - Unicode模式
-
启用完整的Unicode支持
-
正确处理UTF-16代理对和Unicode字符属性
-
示例:
/\p{Script=Greek}/u可以匹配希腊字母 -
支持语言:JavaScript、PHP等
6. y (sticky) - 粘性匹配
-
从目标字符串的当前位置开始匹配(使用
lastIndex属性) -
类似于
^锚点,但针对的是匹配的起始位置 -
示例:在JavaScript中,
/a/y会从lastIndex开始匹配 "a" -
支持语言:JavaScript
7. x (extended) - 扩展模式
-
忽略模式中的空白和注释,使正则表达式更易读
-
示例:在PHP中,
/a b c/x等同于/abc/ -
支持语言:PHP、Perl、Python(作为
re.VERBOSE)
6.贪婪与非贪婪量词
默认情况下,量词(*, +, ?, {})是贪婪的,会尽可能多地匹配字符。在量词后加?可使其变为非贪婪(懒惰)模式:
-
*?:零次或多次,但尽可能少 -
+?:一次或多次,但尽可能少 -
??:零次或一次,但尽可能少 -
{n,m}?:n到m次,但尽可能少
示例:<.*?> 匹配HTML标签时不会跨标签匹配
7.断言
断言(Assertion)是正则表达式中用于指定匹配位置的元字符,它们不匹配任何实际字符,而是匹配字符之间的位置。
简单来说,断言就是"条件",它要求目标字符串必须满足某些条件,但不会消耗字符。
断言的特点
-
零宽度:不占用匹配字符的位置
-
条件检查:只检查是否满足特定条件
-
不影响匹配结果:仅作为匹配的约束条件
断言类型
(?=...) (正向肯定预查)
-
匹配后面跟着特定模式的位置
-
示例:
Windows(?=95|98)匹配后面跟着95或98的"Windows"
(?!...) (正向否定预查)
-
匹配后面不跟着特定模式的位置
-
示例:
Windows(?!95|98)匹配后面不跟着95或98的"Windows"
(?<=...) (反向肯定预查)
-
匹配前面是特定模式的位置
-
示例:
(?<=95|98)Windows匹配前面是95或98的"Windows"
(?<!...) (反向否定预查)
-
匹配前面不是特定模式的位置
-
示例:
(?<!95|98)Windows匹配前面不是95或98的"Windows"
8.运算符优先级
以下是一些常见正则表达式运算符按照优先级从高到低的顺序:
-
转义符号:
\是用于转义其他特殊字符的转义符号。它具有最高的优先级。示例:
\d、\.等,其中\d匹配数字,\.匹配点号。 -
括号: 圆括号
()用于创建子表达式,具有高于其他运算符的优先级。示例:
(abc)+匹配 "abc" 一次或多次。 -
量词: 量词指定前面的元素可以重复的次数。
示例:
a*匹配零个或多个 "a"。 -
字符类: 字符类使用方括号
[]表示,用于匹配括号内的任意字符。示例:
[aeiou]匹配任何一个元音字母。 -
断言: 断言是用于检查字符串中特定位置的条件的元素。
示例:
^表示行的开头,$表示行的结尾。 -
连接: 连接在没有其他运算符的情况下表示字符之间的简单连接。
示例:
abc匹配 "abc"。 -
管道: 管道符号
|表示"或"关系,用于在多个模式之间选择一个。示例:
cat|dog匹配 "cat" 或 "dog"。
9.分组和引用
| 概念 | 语法 | 用途 |
|---|---|---|
| 捕获分组 | (pattern) |
捕获匹配内容并分配编号 |
| 非捕获分组 | (?:pattern) |
分组但不捕获 |
| 命名分组 | (?P<name>pattern) (Python) |
为分组指定名称 |
| 反向引用 | \1, \2 等 |
引用前面匹配的分组 |
| 命名反向引用 | (?P=name) (Python) |
按名称引用分组 |
| 替换引用 | $1, $2 或 \1, \2 |
在替换字符串中引用分组 |