悠悠楠杉
网站页面
正文:
在日常开发中,我们经常需要从字符串中提取符合特定模式的所有内容。传统方法如match配合g标志虽然能实现基础功能,但在需要同时获取分组信息时就会显得力不从心。这正是ES6引入matchAll方法的初衷——它完美解决了这个问题。
与match不同,matchAll会返回一个包含所有匹配完整信息的迭代器,每个匹配结果都包含:
- 完整匹配文本
- 各个捕获组内容
- 匹配的索引位置
- 原始字符串
例如提取HTML标签内容时:
const html = '<div>标题</div><p>正文</p>';
const regex = /<(\w+)>(.*?)<\/\1>/g;
const matches = [...html.matchAll(regex)];
// 输出:
// [
// ["<div>标题</div>", "div", "标题"],
// ["<p>正文</p>", "p", "正文"]
// ]
const post = "今天去了#西湖 #旅游 太美了!";
const tagRegex = /#(\w+)/g;
const tags = [...post.matchAll(tagRegex)].map(m => m[1]);
// 结果: ["西湖", "旅游"]const log = `192.168.1.1 - GET /api/user 200
192.168.1.2 - POST /api/login 404`;
const logRegex = /(\d+\.\d+\.\d+\.\d+).*?(GET|POST)(.*?)(\d{3})/g;
必须使用全局正则
如果忘记添加g标志,会直接抛出TypeError:
javascript
// ❌ 错误示范
'abc'.matchAll(/./); // 抛出错误
迭代器只能消费一次
如果需要重复使用结果,应该先转换为数组:
javascript
const matches = [...str.matchAll(regex)];
性能优化技巧
对于超长文本,建议使用for...of逐项处理而非立即展开:
javascript
for (const match of bigText.matchAll(regex)) {
// 流式处理
}
结合命名捕获组,代码可读性大幅提升:
const text = "订单号:ORD-2023-001 金额:¥299";
const orderRegex = /订单号:(?<order>ORD-\d+-\d+).*?金额:¥(?<amount>\d+)/g;
for (const {groups} of text.matchAll(orderRegex)) {
console.log(groups.order, groups.amount);
}
// 输出: ORD-2023-001 299
通过合理运用matchAll,我们不仅能写出更简洁的代码,还能轻松处理传统方法难以应对的复杂匹配场景。下次遇到需要提取多组匹配数据时,不妨试试这个被低估的ES6利器。