【发布时间】:2017-02-24 20:05:56
【问题描述】:
我正在使用 RegEx 在字符串中查找 URL 子字符串。 我正在使用的正则表达式取自 tohster 的回答 - What's the cleanest way to extract URLs from a string using Python?
RE 是 -
r'^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$'
我已经对其进行了一些更改-
- 在 IPv4 检测部分,我更改了要查找的 IP 范围的顺序。 > 准确地说,在 2 个实例中将
[1-9]\d?|1\d\d|2[01]\d|22[0-3]更改为25[0-5]|2[0-4][0-9]|1[0-> 9]{2}|[1-9][0-9]|[0-9]。- 将 https 组 -
(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)设为可选。
最终版本是-
(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?
我正在使用的最终 RE 似乎很有前途,并且根据我的要求(与原始 RE 相比)有了显着改进,并且可以在 Python 和 Java Script 中工作,除了由于我所做的更改已经导致以下示例给出"catastrophic backtracking" 错误-
asasasasasac31.23.53.122asasassasd
12312312312321.32.34.2312312312321
12.3423423432.234123123.123
31.134232131.231.34
可以在-https://regex101.com/r/i6jDei/1进行测试
我的论点是第一个示例 - asasasasasac31.23.53.122asasassasd 应该有一些巧妙的方式来传递,因为 IP 被非数字字符包围。
另外,有没有办法将上述前两个示例作为有效的 IPv4 地址传递?
为了解决歧义,我会选择尽可能大的地址,即,
31.23.53.122
21.32.34.231
【问题讨论】:
标签: python regex url ip-address ipv4