正则表达式模式

用于搜索和替换文本的模式描述语言,通过组合特殊字符和字面字符来定义字符串模式。

正则表达式模式 (Regular Expression Pattern) 是用于搜索、替换和验证文本的模式描述语言。它将元字符 (特殊字符) 与字面字符组合,定义字符串的匹配模式。它起源于 1950 年代数学家 Stephen Kleene 在形式语言理论中提出的概念,如今几乎所有编程语言和文本编辑器都支持正则表达式。

在 JavaScript 中,可以使用字面量语法 /pattern/flags 或构造函数 new RegExp('pattern', 'flags') 创建正则表达式。test() 判断是否匹配,match() 获取匹配结果,replace() 进行替换,split() 进行分割。字面量语法用于模式固定的情况,构造函数用于动态构建模式,按场景区分使用。

基本元字符包括 . (任意 1 个字符)、^ (行首)、$ (行尾) 和 | (或)。标志包括 g (全局搜索)、i (不区分大小写)、m (多行模式)、s (dotAll 模式) 和 u (Unicode 模式) 等,用于控制匹配行为。ES2022 新增的 d 标志可以获取匹配的索引信息。

正则表达式在实务中的应用范围非常广泛:邮箱和电话号码的格式验证、从日志文件中提取信息、文本编辑器的搜索替换、网页抓取中的数据提取、输入校验等,凡是处理文本的场合都会用到。但正则表达式不适合解析 HTML 或 JSON 这类结构化数据,这些场景应使用专用的解析器。

编写正则表达式时的注意点之一是确保可读性。复杂的模式可以通过带注释的扩展模式 (部分语言支持),或把模式拆分为变量再组装的方式来提高可读性。另一个陷阱是灾难性回溯 (catastrophic backtracking)。像 /^(a+)+$/ 这样重复嵌套的模式,一旦传入不匹配的字符串 (在 a 的连续串末尾加上 b),尝试的组合数就会呈指数级增长。在 Node.js 26 上给出排列了 28 个 a 的输入时,一次 test() 耗时约 17 秒。这就是 ReDoS (正则表达式拒绝服务攻击) 得以成立的机制,其对策是重新审视模式设计 (避免重复嵌套,在支持独占量词或原子组的语言中改用它们),并为匹配的执行时间设置上限。

把用户输入嵌入模式字符串本身时,还需要另外对元字符做转义。如果搜索词中含有 . 或 (,就会被解释为非预期的模式,因此在 JavaScript 中要使用 ES2025 新增的 RegExp.escape(),或自行准备等效的替换处理。需要注意的是,转义是防止意图被误读的措施,并不能防止灾难性回溯。两者的对策要分别实施。

在与字符计数的关联上,正则表达式是文本分析的基础技术。统计与特定模式一致的字符串的出现次数、计算排除空白和符号后的有效字符数、把文本的构成要素 (汉字、平假名、片假名、字母数字) 分类汇总等处理,都会用到正则表达式。字符种类的判定比手写字符编码范围更可靠的做法是使用 Unicode 属性转义,在加上 u 标志的前提下可以写成 \p{Script=Han} (汉字)、\p{Script=Hiragana}、\p{Script=Katakana}。不过这是以码位为单位的判定,因此不适合用来统计像表情符号那样由多个码位构成 1 个字符的对象。

分享这篇文章