返回列表
JavaScript正则表达式指南
自由客七维 2026-03-18 19:13 26

JavaScript中的正则表达式

JavaScript 通过内置对象 RegExp 支持正则表达式,同时字符串方法也提供了正则相关的操作。本文将详细介绍在 JavaScript 中使用正则表达式的各种方式、方法区别以及注意事项。

创建正则表达式

有两种方式创建正则对象:

  1. 字面量:使用斜杠包裹模式,后跟可选标志。例如:const re = /abc/gi;
  2. 构造函数new RegExp("abc", "gi")。当模式需要动态生成时使用构造函数。

正则对象的方法

1. exec()

在字符串中执行匹配,返回一个数组(包含匹配信息及分组)或 null。如果正则带有 g 标志,每次调用 exec 会从上一次匹配的 lastIndex 开始继续查找。

const re = /\d+/g;
const str = "abc123def456";
let match;
while ((match = re.exec(str)) !== null) {
    console.log(`匹配到 ${match[0]} 在索引 ${match.index}`);
}

2. test()

测试字符串是否匹配模式,返回布尔值。常用于表单验证。

if (/^\d+$/.test("123")) {
    console.log("全是数字");
}

字符串方法中使用正则

1. match()

返回字符串匹配正则的结果。

  • 如果正则没有 g 标志,match() 返回和 exec() 相同的结果数组(包含分组)。
  • 如果有 g 标志,返回一个包含所有匹配项的数组(不包含分组)。
"a1b2c3".match(/\d/g);   // ["1", "2", "3"]

2. matchAll() (ES2020)

返回一个迭代器,包含所有匹配结果(包括分组),需要正则带有 g 标志。比 while(exec) 更方便。

const matches = "a1b2c3".matchAll(/(\d)/g);
for (const m of matches) {
    console.log(m[0], m[1]); // 输出数字和捕获组
}

3. search()

返回第一个匹配项的索引,如果找不到返回 -1。

"Hello World".search(/World/); // 6

4. replace()

替换匹配的子串。第二个参数可以是字符串或函数。字符串中可以使用 $n 引用分组。

"2025-03-18".replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1"); // "18/03/2025"

使用函数:

"abc123".replace(/\d+/, function(match) {
    return parseInt(match) * 2;
}); // "abc246"

5. replaceAll() (ES2021)

替换所有匹配项,相当于 replace 配合全局正则,但更直观。

"1 2 3".replaceAll(/\d/g, "x"); // "x x x"

6. split()

用正则分隔字符串。

"a,b  c,d".split(/[,\s]+/); // ["a", "b", "c", "d"]

标志(Flags)详解

标志描述
g全局匹配,查找所有匹配项,而不是在第一个之后停止。
i忽略大小写。
m多行模式,^$ 匹配每行的开始和结束(而不是整个字符串)。
s单行模式,让 . 匹配包括换行符在内的所有字符(ES2018)。
uUnicode 模式,将模式视为 Unicode 代码点序列,正确处理大于 uFFFF 的字符。
y粘附模式,从 lastIndex 位置开始匹配,如果该位置不匹配则失败。

正则表达式中的特殊字符转义

在构造函数中使用字符串时,需要对反斜杠进行转义,例如 new RegExp("\\d+")。而字面量写法更简单直观,推荐优先使用。

性能注意事项

  • 避免在循环中创建正则对象,尤其是字面量,应重用对象。
  • 复杂的正则可能导致灾难性回溯,尽量使用原子组(但 JavaScript 不支持原子组,可以通过某些技巧模拟)。
  • 大量使用 exec 循环时,注意重置 lastIndex 或使用 matchAll

常见陷阱

  • lastIndex 在非全局模式无效:只有全局或粘附模式才影响 exec 的起始位置。
  • test 和 exec 共享 lastIndex:使用全局正则时,交替调用 testexec 可能互相影响,需小心。
  • Unicode 匹配:使用 /.../u 才能正确匹配如 😀 这样的字符(否则会被当作两个字符)。

综合示例

// 验证密码强度:至少8位,包含大小写字母和数字
function validatePassword(pwd) {
    const re = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$/;
    return re.test(pwd);
}

// 提取所有标签名
function extractTagNames(html) {
    const re = /<([a-z]+)[^>]*>/gi;
    return Array.from(html.matchAll(re), m => m[1]);
}

掌握以上内容,您就可以在 JavaScript 项目中熟练运用正则表达式解决各种字符串处理问题。