regex 带有捕获组和字边界的负向前和向后查找

pw9qyyiw  于 2023-02-10  发布在  其他
关注(0)|答案(2)|浏览(122)

我们正在邮件编辑器中自动设置超链接的格式,但希望避免匹配已设置格式的链接。
尝试:构建一个正则表达式,使用负向后查找和负向前查找来排除链接被href=""包围的匹配项。
问题:负向后/向前看不适用于我们的正则表达式:
正则表达式:

/(?<!href=")(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&\/\/=;]*)(?!")/g

用法:

html.match(/(?<!")(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=;]*)(?!")/g);

测试时,我们注意到将 negative lookahead/lookbehind与 positive 版本交换会使其工作,因此只有 negative lookbehind/lookahead不工作。
有人知道为什么这些“消极”的“看后”/“看头"在这个正则表达式中不起作用吗?
谢谢大家!

dgiusagp

dgiusagp1#

有了@Barmar在问题注解中的帮助,很明显问题出在正则表达式的可选开头和结尾。
“基本上,任何允许在否定的环顾旁边有可选内容的东西都可能抵消环顾的效果,如果它能找到一个不在它旁边的更短的匹配的话。“

sulc1iza

sulc1iza2#

如果使用支持可变长度lookbehindAssert的现代JS,您可以在lookbehind中利用非贪婪的可变性。
这使得正则表达式现在可以引入可选的开头,就像您所拥有的那样。

/(?<!href="[^"]*?)(?:https?:\/\/.)?(?:www\.)?[a-zA-Z0-9#%+\-.:=@_~]{2,256}\.[a-z]{2,6}\b[a-zA-Z0-9#%&+\--\/:;=?@_~]*(?!")/

https://regex101.com/r/OdJyZf/1

(?<! href=" [^"]*? )
 (?: https?:// . )?
 (?: www \. )?
 [a-zA-Z0-9#%+\-.:=@_~]{2,256} \. [a-z]{2,6} \b [a-zA-Z0-9#%&+\--/:;=?@_~]* 
 (?! " )

我必须做一个更正,在我的评论中我说过这里的单词边界\b[a-z]{2,6}\b[a-zA-Z0-9#%&+\--/:;=?@_~]有效地删除了下面类中的词类\w
这是真的,但只是对后面的第一个字母。后面所有的字符似乎都包括单词字符,所以它是必要的。这是一个明显的例子,过度思考的东西,不需要。
整个正则表达式应该能够在类中使用\w重写,除非需要ASCII。
注意,这只适用于新的JS引擎和C#(当然)。

相关问题