跳到主要内容
LeedyBox
支持我们

正则表达式基础

正则表达式(regex)是描述文本的模式。本指南介绍最常用的基本构件,以及导致匹配缓慢或出乎意料的常见陷阱。

字面字符与字符类

大多数字符匹配其自身:模式 cat 会找到文本“cat”。有些字符具有特殊含义,例如 . * + ? ( ) [ ] { } ^ $ | \。要按字面匹配其中某个字符,请用反斜杠转义,例如用 \. 匹配句点。

字符类匹配集合中的一个字符。[abc] 匹配 a、b 或 c;[a-z] 匹配一个小写 ASCII 字母;[^0-9] 匹配任何非数字字符。常用的简写有 \d(数字)、\w(字母、数字或下划线)、\s(空白字符),以及它们的反义 \D、\W 和 \S。点 . 匹配除换行以外的任意字符。

在 JavaScript 中,\w 和 \d 只涵盖 ASCII 字符。要匹配任何语言的字母,请配合 u 标志使用 \p{L} 等 Unicode 属性。

量词与锚点

量词指定前一项可以重复的次数:

语法 含义 示例
* 0 次或多次 ab* 匹配 a、ab、abbb
+ 1 次或多次 \d+ 匹配 7 或 2026
? 0 次或 1 次 colou?r 匹配 color 和 colour
{n,m} n 到 m 次 \d{2,4} 匹配 2 到 4 位数字

锚点匹配的是位置而不是字符。^ 表示输入的开头,$ 表示输入的结尾(使用 m 标志时为每一行的开头和结尾)。\b 是单词边界,因此 \bcat\b 能找到“cat”,但不会匹配“concatenate”。验证整个值时,请锚定两端:^\d{5}$ 只接受恰好五位数字,不接受其他内容。

分组与捕获

圆括号将模式的一部分分组,使量词或选择作用于整组:(ab)+ 重复“ab”,(jpg|png) 匹配两个单词之一。普通分组还会捕获匹配的文本,您可以在替换中以 $1、$2 等形式重复使用。

(?<year>\d{4}) 这样的命名组让模式更易读,并可通过 $<year> 引用。如果只需要分组,可以使用非捕获组 (?:...),避免产生用不到的捕获。LeedyBox 正则表达式测试会列出每个匹配及其捕获组,并预览替换结果。

标志

标志会改变整个模式的行为。常用的 JavaScript 标志有:

  • g(global):查找所有匹配,而不只是第一个。
  • i(ignore case):将大写和小写视为相同。
  • m(multiline):^ 和 $ 在每个换行处匹配。
  • s(dotAll):. 也匹配换行。
  • u(unicode):启用支持 Unicode 的匹配和 \p{...} 类。

JavaScript 还有 y(sticky)和 d(匹配索引),测试工具也都支持。

贪婪与惰性,以及灾难性回溯

量词默认是贪婪的:它们尽可能多地匹配,如果模式的其余部分匹配失败,再逐个退还字符。对于文本 <b>bold</b>,模式 <.+> 会匹配整个字符串。加上 ? 会让量词变为惰性,因此 <.+?> 只匹配 <b>。<[^>]+> 这样的否定字符类通常更清晰,也更快。

包括 JavaScript 在内的大多数正则引擎都使用回溯。(a+)+$ 这样的嵌套量词或相互重叠的选择分支,可能会在匹配失败时让引擎尝试海量的组合,从而使页面或服务器卡死。这被称为灾难性回溯;面对不可信的输入时,它可能被用于拒绝服务攻击(ReDoS)。请避免对同一组字符嵌套量词,优先使用具体的字符类而不是 .*,并用不匹配的长输入测试模式。

不同的正则方言

正则表达式没有统一的标准。JavaScript、Python、Java、.NET、PCRE(PHP 所用)、Go 以及各种数据库支持的语法都略有不同。后行断言、占有量词、命名组语法、Unicode 类和替换语法各不相同。例如,Go 的 RE2 引擎不支持环视和反向引用。

LeedyBox 正则表达式测试使用您浏览器的 JavaScript 引擎。在这里可用的模式在其他语言中可能需要修改,因此请在实际运行的环境中再次测试。

常见问题

为什么我的模式只匹配第一处?

没有 g 标志时,JavaScript 在第一个匹配后就会停止。启用 g 即可查找所有匹配。

正则表达式能验证电子邮件地址吗?

正则表达式可以检查一个值看起来是否合理,但无法确认该地址是否存在。通常的验证方法是发送确认邮件。

为什么在多行文本中 ^ 只匹配一次?

默认情况下,^ 和 $ 针对的是整个输入。开启 m 标志后,它们会在每一行的开头和结尾匹配。