正则匹配结果出现多余换行符分组的原因及解决建议
正则匹配结果出现多余换行符分组的原因及解决建议
嗨,我来帮你搞明白这个问题~
你现在想要匹配字符串里start和end之间的内容,用了正则/start((.|\n)*)end/m,结果发现output[2]是个换行符,疑惑它的来源对吧?
原因解析
你的正则里((.|\n)*)包含了两层捕获组:外层的(...)是捕获组1,用来包裹你真正想要的中间内容;而里面的(.|\n)是捕获组2。
正则里的捕获组如果处于重复匹配(比如*、+这类量词)内部时,它不会保存每次匹配的结果,只会保留最后一次匹配到的内容。这里(.|\n)*会逐个匹配start到end之间的每一个字符(包括换行),每匹配一个字符,捕获组2就会更新一次,最后一次匹配到的就是end前面的那个换行符,所以output[2]就变成了这个换行啦。
解决建议
给你两个简单的改进方案:
方案一:使用非捕获组
把内部的(.|\n)改成非捕获组(?:.|\n),非捕获组不会生成额外的匹配项,只会用来分组匹配规则。修改后的正则是:const output = test.match(/start((?:.|\n)*)end/m);这样
output里就只有output[0](整个匹配的完整字符串)和output[1](你需要的中间内容),不会再出现多余的output[2]。方案二:更简洁高效的写法
用[\s\S]代替(.|\n),[\s\S]可以匹配所有字符(包括换行符),比(.|\n)更简洁。如果你的字符串里可能有多个end,可以加上非贪婪量词*?,避免匹配到最后一个end。修改后的正则是:const output = test.match(/start([\s\S]*?)end/);这个写法不仅不会生成多余捕获组,匹配效率也更高,还能精准匹配到最近的
end。
备注:内容来源于stack exchange,提问作者Jeanluca Scaljeri
相关产品推荐
相关产品推荐

