正则表达式
1. 基础元字符与转义
-
.:匹配除换行符以外的任意单个字符。(在开启s修饰符后可匹配包括换行符在内的所有字符)。 -
\:转义字符。用于取消元字符的特殊含义(如\.匹配真实的句号),或引入特殊的预定义字符。 -
|:逻辑或(分支)。例如cat|dog匹配 "cat" 或 "dog"。注意:|的优先级极低,通常需配合括号使用,如(cat|dog)s。
2. 字符集合 (Character Classes)
用于匹配方括号内的任意一个字符。
-
[abc]:匹配 "a"、"b" 或 "c" 中的任意一个。 -
[^abc]:脱字符^在中括号内表示取反,匹配除了 "a", "b", "c" 之外的任意字符。 -
[a-z]:范围匹配,匹配所有小写英文字母。 -
[a-zA-Z0-9]:组合范围,匹配所有大小写字母和数字。 -
注意:在
[]内,大多数元字符(如.,*,?)会失去特殊含义,变为普通字符。
3. 预定义字符族 (Shorthand Classes)
大写字母通常是小写字母的取反。
-
\d:匹配数字,等价于[0-9]。 -
\D:匹配非数字,等价于[^0-9]。 -
\w:匹配单词字符(字母、数字、下划线),等价于[a-zA-Z0-9_]。 -
\W:匹配非单词字符。 -
\s:匹配空白字符(空格、制表符\t、换行符\n、回车符\r等)。 -
\S:匹配非空白字符。
4. 量词与贪婪模式 (Quantifiers & Greediness)
量词用于指定其前面的一个字符或一个分组的出现次数。
-
基本量词:
-
*:匹配 0 次或多次(\(\ge\) 0)。 -
+:匹配 1 次或多次(\(\ge\) 1)。 -
?:匹配 0 次或 1 次。 -
{n}:精确匹配 \(n\) 次。 -
{n,}:匹配至少 \(n\) 次。 -
{n,m}:匹配 \(n\) 到 \(m\) 次。
-
-
贪婪与懒惰 (Greedy vs. Lazy):
-
默认情况下,量词是贪婪的,会尽可能多地匹配字符。
-
在量词后加上
?,将其变为懒惰(非贪婪)模式,会尽可能少地匹配字符。 -
示例:对于字符串
"<div>test</div>":-
贪婪模式
<.*>会匹配整个"<div>test</div>"。 -
懒惰模式
<.*?>会匹配"<div>"。
-
-
5. 边界断言 (Anchors)
边界断言不消费字符(不占用匹配文本的宽度),它们只匹配特定的位置。
-
^:匹配字符串的起始位置。(多行模式下匹配每行的开头)。 -
$:匹配字符串的结束位置。(多行模式下匹配每行的结尾)。 -
\b:匹配单词边界。即\w和\W之间的位置,或者\w与字符串开头/结尾之间的位置。 -
\B:匹配非单词边界。
6. 分组与捕获 (Grouping & Capturing)
使用小括号 () 将多个字符组合为一个整体,同时会被引擎“捕获”到内存中供后续引用。
-
(...):捕获分组。默认按左括号的出现顺序从 1 开始编号。 -
\1,\2:反向引用(Backreference)。在正则表达式内部引用之前捕获到的第 1、第 2 个分组匹配到的具体文本。- 示例:
(\w+)\s+\1可以匹配重复的单词,如 "hello hello"。
- 示例:
-
(?:...):非捕获分组。仅用于逻辑组合和应用量词,不保存匹配结果,提高匹配性能。 -
(?<name>...)或(?'name'...):命名捕获分组。为分组指定一个明确的名称,提取数据时可通过名称索引。
7. 环视 / 零宽断言 (Lookarounds)
高级特性,用于在匹配时设定条件,但不消费字符(即断言部分的内容不会出现在最终的匹配结果中)。
-
(?=...):肯定正向环视(Positive Lookahead)。要求当前位置的右侧必须匹配...。- 示例:
Windows(?=95|98)匹配 "Windows98" 中的 "Windows",但不匹配 "Windows3.1"。
- 示例:
-
(?!...):否定正向环视(Negative Lookahead)。要求当前位置的右侧不能匹配...。 -
(?<=...):肯定逆向环视(Positive Lookbehind)。要求当前位置的左侧必须匹配...。 -
(?<!...):否定逆向环视(Negative Lookbehind)。要求当前位置的左侧不能匹配...。
8. 常用修饰符 / 模式标志 (Modifiers / Flags)
修饰符通常写在正则表达式定界符之外(如 /pattern/ig)。
-
i(Ignore case):忽略大小写。 -
g(Global):全局匹配。找到所有匹配项,而不是在找到第一个匹配后停止(特定语言 API 中的概念,如 JS)。 -
m(Multiline):多行模式。使^和$除了匹配整个字符串的开头和结尾外,还能匹配每一行的开头和结尾。 -
s(Singleline / Dotall):单行模式。使.能够匹配包括换行符在内的所有字符。 -
x(Extended / Free-spacing):扩展模式。忽略表达式中的空白字符和#注释,便于编写复杂正则。
9. 性能陷阱:灾难性回溯 (Catastrophic Backtracking)
-
成因:当正则表达式中存在嵌套的量词(如
(a+)+或.*.*),且目标字符串在其末尾导致匹配失败时,正则引擎会尝试所有可能的排列组合,导致 CPU 占用率飙升,程序假死。 -
规避方案:
-
尽可能明确匹配的字符集,避免滥用
.*(如用[^"]*替代.*?匹配引号内的内容)。 -
使用固化分组(Atomic Grouping)
(?>...),一旦匹配成功,丢弃内部的所有备用状态(不支持回溯)。
-