条件Python正则表达式匹配可能包含第二个冒号的URL

时间:2018-02-25 03:12:04

标签: python regex regex-negation

我正在尝试匹配不包含第二个冒号的URL或相对路径(在协议中的一个之后,例如http(s)://)。

我想拒绝

形式的网址
https://en.wikipedia.org/wiki/Special:BookSources/0-8018-1841-9

或表格的路径

/wiki/Special:BookSources/0-8018-1841-9

有一个例外。我希望保留带有第二个冒号的那些如果后跟一个下划线:

https://en.wikipedia.org/wiki/The_Post_Card:_From_Socrates_to_Freud_and_Beyond

/wiki/The_Post_Card:_From_Socrates_to_Freud_and_Beyond`

我现在拥有的正则表达式(基于 this questionthis one)是^[^:]*[:]*.*(/wiki/)[^:]+$,它解决了我要求的第一部分,但不是第二部分。

我如何解释冒号后跟下划线的特殊情况?

2 个答案:

答案 0 :(得分:1)

负向前瞻可能在这里最有意义:

^https?://(?!.*:[^_]).*wiki.*

请注意,/wiki/Special:BookSources/0-8018-1841-9严格来说,不是URL,因为没有协议。相反,它是一条道路。您可能需要稍微修改我上面写的内容,但负面前瞻是解决您问题的简单方法。

答案 1 :(得分:1)

当处理各种形式,不同方案或没有域锚的url路径时,我喜欢使用urlpath。

安装:

pip install urlpath

您可以使用urlpath库检查域之后的url的每个部分,以查看它们是否包含没有下划线的冒号。如果要避免使用正则表达式,此示例很有用。

示例:

>>> from urlpath import URL
>>> url = URL('https://en.wikipedia.org/wiki/Special:BookSources/0-8018-1841-9')
>>> any(':' in i and not ':_' in i for i in url.parts[1:])
True
>>> url2 = URL('https://en.wikipedia.org/wiki/The_Post_Card:_From_Socrates_to_Freud_and_Beyond')
>>> any(':' in i and not ':_' in i for i in url2.parts[1:])
False

在此示例中,any语句对于要忽略的URL返回true。如果你想让这个例子更具功能性,你也可以使用正则表达式进行过滤。

>>> any(re.search(':[^_]',i) for i in url.parts[1:])
True
>>> any(re.search(':[^_]',i) for i in url2.parts[1:])
False

如果您使用这些网址做任何请求,我建议您使用urlpath库。它结合了pathlib的灵活性,功能urllib.parse,以及构建它的请求。

>>> url.get()
<Response [200]>