正则表达式split仅返回匹配最后字符,如何保留完整匹配内容
解决
split()正则分割后无法保留完整匹配项的问题 我一眼就看出问题出在你的正则表达式的捕获组上!你当前的正则/\[~(\d|-|[a-f]){32,36}\]/里,(\d|-|[a-f])是一个捕获组,而split()方法在遇到带捕获组的正则时,会把捕获组匹配到的内容(也就是那些32-36位的字符和短横线)加入结果数组,而不是你想要的完整[~xxx]格式字符串。
快速修复方案
把整个[~xxx]的匹配模式包裹在一个捕获组里,同时把原来的内部捕获组改成非捕获组(避免多余的捕获),修正后的代码如下:
const regEx = /(\[~(?:\d|-|[a-f]){32,36}\])/; const str = "How [~75e0a072-6464-4e00-8229-a3b6b799a673] to [~457713c4-a752-4eed-b835-28f7ef74b682] also [~57713c4-a752-4eed-b835-28f7ef74b682] you?"; const res = str.split(regEx); console.log(res);
执行后你会得到完全符合预期的结果:
["How ", "[~75e0a072-6464-4e00-8229-a3b6b799a673]", " to ", "[~457713c4-a752-4eed-b835-28f7ef74b682]", " also ", "[~57713c4-a752-4eed-b835-28f7ef74b682]", " you?"]
为什么这样有效?
- 非捕获组
(?:...):把原来的(\d|-|[a-f])改成(?:\d|-|[a-f]),这样正则就不会单独捕获这部分内容,避免干扰最终的结果数组。 - 外层捕获组:用
(\[~(?:...)])把整个[~xxx]的匹配规则包裹起来,split()会将每个完整的匹配项作为元素插入到分割后的数组中,完美保留你需要的格式。
另一种可选方案(正向断言)
如果你不想用捕获组,也可以用正向先行/后行断言来实现分割,不过需要过滤掉分割产生的空字符串:
const regEx = /(?=\[~(?:\d|-|[a-f]){32,36}\])|(?<=\[~(?:\d|-|[a-f]){32,36}\])/; const str = "How [~75e0a072-6464-4e00-8229-a3b6b799a673] to [~457713c4-a752-4eed-b835-28f7ef74b682] also [~57713c4-a752-4eed-b835-28f7ef74b682] you?"; const res = str.split(regEx).filter(Boolean); console.log(res);
这种方式是在每个[~xxx]的前后位置进行分割,然后通过filter(Boolean)去掉空字符串,同样能得到目标结果,但捕获组的方式更直观简洁。
内容的提问来源于stack exchange,提问作者6axter82
相关产品推荐
相关产品推荐

