matchall() 是处理多匹配、带捕获组正则的理想选择,可高效提取并结构化注释(如 // todo、/ hack /、{@warn}),返回含完整捕获信息的可迭代对象,避免 exec() 循环的繁琐与错误。

matchAll() 是处理多匹配、带捕获组的正则场景的理想选择,特别适合提取并聚合结构化注释(如 // TODO、/* FIXME */、{@note ...} 等)。它返回一个可迭代对象,能完整保留每次匹配的全部信息(含捕获组),避免手动循环 exec() 的繁琐和易错。
明确注释格式并编写带捕获组的正则
聚合的前提是统一识别逻辑。例如,若需提取三类常见注释:
-
// TODO: 重构缓存逻辑→ 匹配行内单行注释 -
/* HACK: 避免 Safari flex bug */→ 匹配块级注释 -
{@warn 忽略空值可能导致崩溃}→ 匹配 JSDoc 风格标记
可构造一个「或」式正则,并为关键部分(类型、内容)设置命名捕获组:
const commentRegex = /(?:\/\/\s*(?用 matchAll() 提取所有匹配并归一化结构
调用 matchAll() 后,遍历结果,从不同捕获组中提取 type 和 content,统一成标准对象:
结果为数组:[{type:"TODO", content:"加入错误重试", index:0}, {...}],已结构化、可排序、可过滤。
按需聚合:分组统计、去重合并或生成报告
得到结构化数组后,聚合方式灵活:
-
按类型分组:
Object.groupBy(allComments, ({type}) => type)(ES2024)或用reduce -
提取唯一内容:
[...new Set(allComments.map(c => c.content))] -
生成 Markdown 报告:
allComments.map(c => `- [${c.type}] ${c.content}`).join('\n')
例如统计各类型数量:
const counts = allComments.reduce((acc, {type}) => {\n acc[type] = (acc[type] || 0) + 1;\n return acc;\n}, {}); // { TODO: 1, HACK: 1, warn: 1 }
注意边界与健壮性
真实文本中需考虑:
- 注释可能跨行(尤其块注释),此时正则需加
s标志(/.../gs)使.匹配换行符 - 避免匹配字符串字面量中的伪注释(如
const s = "// TODO: not real";),需结合语法分析器(如 Acorn)更安全;纯正则方案可加负向先行断言排除引号内位置(较复杂,视精度要求取舍) -
matchAll()要求正则含g标志,否则抛错










