Skip to content

正则表达式

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 占用率飙升,程序假死。

  • 规避方案:

    1. 尽可能明确匹配的字符集,避免滥用 .*(如用 [^"]* 替代 .*? 匹配引号内的内容)。

    2. 使用固化分组(Atomic Grouping) (?>...),一旦匹配成功,丢弃内部的所有备用状态(不支持回溯)。