正则表达式 - 在编码的电话 URL 中匹配“%20”

Regex - match '%20' in encoded tel URL

提问人:Vitalie R. 提问时间:11/10/2023 最后编辑:Vitalie R. 更新时间:11/14/2023 访问量:75

问:

我有以下正则表达式:

 (?:[\s:]|\d+(?:-|.)|^)(?(\d{3}))?[- .]?(\d{3})[- .]?(\d{4})(?=<|\s|$)

复制正则表达式时,看起来一些转义反斜杠丢失了,所以这里是正确的正则表达式:(?:[\s:]|\d+(?:-|\.)|^)\(?(\d{3})\)?[- \.]?(\d{3})[- \.]?(\d{4})(?=<|\s|$)

它用于 Chrome 上的 Tel Linker 扩展程序,以正确格式化网页上的电话号码链接。

但是,当 URL 中的空格使用“%20”编码时,它无法正确格式化 tel 链接: 例如:

https://someresource.com/tel:(904)%20640-8301
https://someresource.com/tel:(904)%20640%208301

不幸的是,我没有使用正则表达式的经验,因此非常感谢任何帮助/建议。

javascript 正则表达式 google-chrome tel

评论

1赞 mplungjan 11/10/2023
Regex101 抱怨可选括号。您可能需要\(?(\\d{3})\)?
1赞 icecub 11/10/2023
@vanowm 确保将 Regex101 设置为 ECMAScript。只剩下 1 个错误,只是 OP 在第三个问号后忘记了一个。:
0赞 The fourth bird 11/10/2023
是否要匹配该部分是必填项的 URL?/tel:
0赞 Vitalie R. 11/10/2023
从我从 Tel Linker 概述中可以听到的内容来看,它会检测 tel 链接,然后尝试使用提供的正则表达式格式化号码。我假设它只采用 /tel: 之后的部分,然后应用正则表达式来标识数字组,然后将它们转换为可以使用选定的语音应用程序打开的可单击链接。

答:

1赞 dsalex1 11/10/2023 #1

根据 regex101,您提供的正则表达式无效

(?:[\s:]|\d+(?:-|.)|^)(?(\d{3}))?[- .]?(\d{3})[- .]?(\d{4})(?=<|\s|$)

没有 ?在捕获组中,它是有效的,并且似乎与正确的内容匹配:

(?:[\s:]|\d+(?:-|.)|^)((\d{3}))?[- .]?(\d{3})[- .]?(\d{4})(?=<|\s|$)

负责匹配 TEL 中的空格,因此将其替换为也匹配的正则表达式将解决以下问题:[- .]%20(?:[- .]|%20)

(?:[\s:]|\d+(?:-|.)|^)((\d{3}))?(?:[- .]|%20)?(\d{3})(?:[- .]|%20)?(\d{4})(?=<|\s|$)

评论

0赞 Vitalie R. 11/10/2023
感谢您的帮助,确实正则表达式无效。我尝试了建议的解决方案,但它与第一组数字(即上述示例中的 904)不匹配。
1赞 vanowm 11/10/2023 #2

正如@mplungjan指出的,您的正则表达式无效。

试试这个:

(?:[\s:]|\d+(?:-|.)|^)\(?(\d{3})\)?(?:%20)*(?:[- .]+(?:%20)*)?(\d{3})(?:(?:%20)*[- .]*(?:%20)*)?(\d{4})(?=<|\s|$)

如果你把它作为一个字符串,你将需要转义每一个:\

(?:[\\s:]|\\d+(?:-|.)|^)\\(?(\\d{3})\\)?(?:%20)*(?:[- .]+(?:%20)*)?(\\d{3})(?:(?:%20)*[- .]*(?:%20)*)?(\\d{4})(?=<|\\s|$)

经测试:

https://someresource.com/tel:(904)640-8301
https://someresource.com/tel:(904)%20640%208301
https://someresource.com/tel:(904)%20640-8301
https://someresource.com/tel:(904)%20640 - 8301
https://someresource.com/tel:(904)%20640%20-%208301

感谢 @Casimir et Hippolyte 的建议

评论

0赞 Vitalie R. 11/10/2023
感谢您的帮助!第一个建议是有效的!我在 regex101 上对其进行了测试,并正在生成 corect 组。
1赞 Casimir et Hippolyte 11/14/2023
(?:(?:%20)*|(?:%20)*[- .]*(?:%20)*)?没有意义:“一个可选组,其中所有备选方案都可能是空的”。它的作用与或更好。同样的问题。而不是写 ,使用带有否定字符类的否定展望:(= - 请注意,这句话也允许字符串的结尾)。(?:%20)*[- .]*(?:%20)*(?:%20)*(?:[- .]+(?:%20)*)?(?:(?:%20)?|(?:%20)*[- .]*(?:%20)*)?(?=<|\s|$)(?![^<\s])not followed by a character that is **not** a "greater than" symbol nor a white-space