Avatar ·

如何在 JavaScript 正则表达式中访问匹配的组?

大家好!我是 JavaScript 新手,正在学习正则表达式。我有一个字符串,例如 `"Сегодня 25.12.2023"`,我想从中分别提取日、月和年。我写了这样的代码: ```javascript let str = "Сегодня 25.12.2023"; let regex = /(\d{2})\.(\d{2})\.(\d{4})/; let result = regex.exec(str); console.log(result); ``` 在控制台中我看到一个数组,但我不明白如何获取具体的日、月和年。我试过写 `result[1]`、`result[2]`、`result[3]`——这确实有效,但我觉得不太方便。而且,如果我使用 `str.match(regex)`,在没有匹配时结果会不同。 请解释一下,在 JavaScript 中如何正确访问捕获组?什么时候用 `exec()`,什么时候用 `match()`?还有,能否给组命名,以避免在索引中混淆?感谢您的详细讲解和示例。 <<>>

JavaScript 中捕获组的基础知识

在正则表达式中,捕获组用于提取匹配的子字符串。当你用 `exec()` 或 `match()` 方法时,结果数组中索引从 0 开始:`result[0]` 是整个匹配(例如 `"25.12.2023"`),接下来 `result[1]` 是第一个捕获组(`日`),`result[2]` 是第二个(`月`),`result[3]` 是第三个(`年`)。回到你的示例,`result[1]` 就是日期的 `"25"`,`result[2]` 是 `"12"`,`result[3]` 是 `"2023"`。

如果不习惯数字索引,JavaScript 确实支持命名捕获组(ES2018 引入)。语法是 `(?pattern)`。例如:

```javascript let str = "Сегодня 25.12.2023"; let regex = /(?\d{2})\.(?\d{2})\.(?\d{4})/; let result = regex.exec(str); if (result) { console.log(result.groups.day); // "25" console.log(result.groups.month); // "12" console.log(result.groups.year); // "2023" } ```

命名组让代码更易读。如果 `str.match(regex)` 没有匹配,则返回 `null`;而 `exec()` 在没有匹配时也返回 `null`。因此两种方法都需要先检查结果是否是 `null`,再访问组。

`exec()` 和 `match()` 的区别

  • `exec()` 是正则对象的方法。它不只是返回第一个匹配,还可以在全局(带 `g` 标志)或粘性(带 `y` 标志)正则表达式中多次调用,每次返回下一个匹配,并更新 `lastIndex` 属性。适合循环提取。
  • `match()` 是字符串的方法。如果正则带有 `g` 标志,则返回所有完整匹配的数组(不包含捕获组);如果没有 `g` 标志,则返回与 `exec()` 相同的数组(第一个匹配及捕获组)。无匹配时返回 `null`。

对于你的需求(一次性提取日期各部分),两者都可以。但如果你需要全局查找多个日期,推荐不带 `g` 的 `match()` 或直接用 `exec()` 手动循环。

最后,建议总是使用命名组或给变量起有意义的名称(如 `const day = result[1]`)来避免索引混淆。希望这能帮到你!