尝试在 JavaScript 中使用 Gruber 的“改进的”URL 匹配正则表达式模式时,如何修复“无效组”错误?
Posted
技术标签:
【中文标题】尝试在 JavaScript 中使用 Gruber 的“改进的”URL 匹配正则表达式模式时,如何修复“无效组”错误?【英文标题】:How do I fix "invalid group" error when attempting to use Gruber's "improved" URL matching regexp pattern in JavaScript? 【发布时间】:2022-01-24 00:23:31 【问题描述】:我正在尝试将 John Gruber 的 An Improved Liberal, Accurate Regex Pattern for Matching URLs 集成到我的一个 javascript 中,但是 WebKit 的检查器(在 Mac 的 Google Chrome 5.0.375.125 中)给出了“无效组”正则表达式语法错误。
Gruber 的原始正则表达式如下:
(?i)\b((?:[a-z][\w-]+:(?:/1,3|[a-z0-9%])|www\d0,3[.]|[a-z0-9.\-]+[.][a-z]2,4/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\];:'".,<>?«»“”‘’]))
我的 JavaScript 中带有正则表达式的行如下(带有正斜杠反斜杠转义):
tweet_text = tweet_text.replace(/(?i)\b((?:[a-z][\w-]+:(?:\/1,3|[a-z0-9%])|www\d0,3[.]|[a-z0-9.\-]+[.][a-z]2,4\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\];:'".,<>?«»“”‘’]))/gi, '<a href="$1">$1</a>');
Google Chrome (V8?) 错误如下:
Uncaught SyntaxError: Invalid regular expression: /(?i)\b((?:[a-z][\w-]+:(?:\/1,3|[a-z0-9%])|www\d0,3[.]|[a-z0-9.\-]+[.][a-z]2,4\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\];:'".,<>?«»“”‘’]))/: Invalid group
而Safari报错如下:
SyntaxError: Invalid regular expression: unrecognized character after (?
他声称它应该可以在现代 JavaScript 正则表达式解释器中工作,我认为 WebKit 和 V8 可以。 JavaScript的正则表达式语法不支持(?:
(该死的谷歌没有索引标点符号!)分组语法?我只是错过了逃避什么吗?
【问题讨论】:
【参考方案1】:啊,它是正则表达式开头的模式修饰符(即(?i)
)!
我浏览了Regular-Expressions.info's datails on "JavaScript's Regular Expression Flavor",特别是不支持的列表,还有“模式修饰符”,我已经在正则表达式的正斜杠之后指定了它。把它撕下来,一切看起来都很好。
所以,我的 JavaScript 正则表达式现在如下:
/\b((?:[a-z][\w-]+:(?:\/1,3|[a-z0-9%])|www\d0,3[.]|[a-z0-9.\-]+[.][a-z]2,4\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\];:'".,<>?«»“”‘’]))/gi
【讨论】:
我实际上在匹配“example.com”时遇到了问题。 'example.com' 和 'www.example.com' 都有效。你有什么想法吗? 通过删除域名第三个选项末尾的\/,我可以使它工作:\b((?:[a-z][\w-]+:(?:\/1,3|[a-z0-9%])|www\d0,3[.]|[a-z0-9.\-]+[.][a-z]2,4)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s
!()[];:'".,? «»“”'']))`
啊,我看到 Gruber 故意遗漏了 example.com 的案例,但是,这似乎是一个常见的案例。
我同意这是一个常见的情况并且会很有用。也就是说,我理解 Gruber 不希望与特定 TLD 匹配以实现灵活性和前向兼容性,也不希望它与 filename.ext
匹配。
经过一天的努力,我最终得到:gist.github.com/920312以上是关于尝试在 JavaScript 中使用 Gruber 的“改进的”URL 匹配正则表达式模式时,如何修复“无效组”错误?的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用 localStorage 在 JavaScript 中保存和加载带有对象的数组时出错
尝试使用 Rhino,getEngineByName("JavaScript") 在 OpenJDK 7 中返回 null
如何在 Laravel 8 中使用 JavaScript 获取?
在 Chrome webkit 检查器中不断生成“不安全的 JavaScript 尝试使用 URL 访问框架...”错误