使用JavaScript正则引擎按行首相同单词分组合并行的问题求解
问题原因
原有正则无法输出正确结果,核心问题有三点:
- 正则替换默认从左到右线性扫描文本,单次替换仅处理首次命中的匹配段,已被匹配消耗的文本不会进入后续匹配流程,分散在文本不同位置的同前缀行无法被一次扫描全部捕获。
- 惰性量词
[\s\S]*?仅会匹配离当前捕获行最近的一个同前缀行,匹配完成后扫描指针直接跳到本次匹配内容的末尾,更远位置的同前缀行会被直接跳过。 - 原正则的捕获组分组逻辑不合理,会保留多余换行符,导致结果出现空行。
可行方案
纯正则实现需要循环执行替换直到没有可匹配项,配合调整后的正则规则即可得到正确结果:
正则表达式
/(^\w+\b)(.*)(\n[\s\S]*?)\1\b(.*)\n?/gm
替换规则
$1$2$4$3
规则说明
- 开启多行匹配模式
m和全局匹配模式g,保证^能匹配每一行的开头,且替换能处理所有命中片段 - 捕获组1
(^\w+\b):匹配行首的前缀关键词(如C1、C2) - 捕获组2
(.*):匹配前缀关键词首次出现时,所在行除前缀外的剩余内容(不含行尾换行) - 捕获组3
(\n[\s\S]*?):惰性匹配首次出现行的行尾换行,以及首次行和后续同前缀行之间的所有内容 \1\b:反向引用之前捕获的前缀关键词,定位后续出现的重复同前缀行- 捕获组4
(.*):匹配重复同前缀行除前缀外的剩余内容 \n?:吃掉重复同前缀行的行尾换行,避免出现多余空行- 替换时将重复行的内容直接拼接到首次出现行的末尾,保留两行之间的其他内容,删除重复的前缀行
- 循环执行替换,直到文本中不存在可匹配的重复前缀行,即可完成所有行的合并。
代码示例(JavaScript)
const input = `C1 10 C2 20 C3 30 C2 40 C4 50 C3 60`; const regex = /(^\w+\b)(.*)(\n[\s\S]*?)\1\b(.*)\n?/gm; let result = input; // 循环替换直到无匹配项 while (regex.test(result)) { result = result.replace(regex, '$1$2$4$3'); } console.log(result); /* 最终输出: C1 10 C2 20 40 C3 30 60 C4 50 */
内容的提问来源于stack exchange,提问作者straj
相关产品推荐
相关产品推荐

