正则表达式无法匹配字符串中全部<a>标签,求问题原因及解决方法
问题描述
给定字符串:
const str = `This <a href="https://regex101.com/" data-link-id="431ebea7-1426-65a5-8383-55a27313dc51">is a test link</a> which has a hyperlink, and <a href="https://regex102.com/" data-link-id="d62dc3eb-7b3d-953e-4d7a-987448e6928d">this is also</a> a hyperlink.`
我尝试用正则匹配所有<a>标签,但当前正则返回的是整个字符串:
str.match(/<a href=".+" data-link-id="[0-9A-Z-a-z]{1,}">(.*?)<\/a>/)
期望得到包含两个元素的数组,但实际结果不符。替换(.*?)为.+或[A-Za-z0-9\s]+后问题依旧,请问问题出在哪?
问题原因与解决办法
贪婪匹配+未开启全局模式是核心问题
正则里的.+是贪婪模式,会从第一个<a href="开始,一直匹配到最后一个符合data-link-id="..."的位置,直接把两个<a>标签中间的内容也吞进去,最终匹配整个字符串。另外match()方法默认只返回第一个匹配结果,要抓取所有匹配项,必须加上全局标志g。字符集遗漏连字符
data-link-id的值里包含连字符-,但你写的[0-9A-Z-a-z]字符集没包含它——不过因为前面的贪婪匹配把这个问题掩盖了,等你修正贪婪后,这个问题会导致data-link-id匹配失败,所以得把-加进去,或者更简单的用[^"]+来匹配属性值(因为属性值用双引号包裹,匹配到下一个双引号为止更准确)。修正后的正则示例
改成非贪婪匹配,加上全局标志g,同时修正属性值的匹配规则:str.match(/<a href=".+"? data-link-id="[^"]+">(.*?)<\/a>/g)要是想更严谨,把
href里的.+也改成非贪婪的.+?,避免href值里出现意外空格导致匹配出错:str.match(/<a href=".+"? data-link-id="[^"]+">(.*?)<\/a>/g)这样就能得到包含两个
<a>标签的数组了。
内容的提问来源于stack exchange,提问作者Mike K
相关产品推荐
相关产品推荐

