尝试在 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()&lt;&gt;]+|\(([^\s()&lt;&gt;]+|(\([^\s()&lt;&gt;]+\)))*\))+(?:\(([^\s()&lt;&gt;]+|(\([^\s()&lt;&gt;]+\)))*\)|[^\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 访问框架...”错误

尝试使用循环向 Javascript 对象添加多个属性

尝试使用 JavaScript 将 css 样式添加到 iframe