条件 Python 正则表达式以匹配可能包含第二个冒号的 URL
Conditional Python regex to match URLs that may contain a second colon
我正在尝试匹配不包含第二个冒号(在协议中的冒号之后,例如 http(s)://
)的 URL 或相对路径。
我想拒绝
形式的 URL
https://en.wikipedia.org/wiki/Special:BookSources/0-8018-1841-9
或形式的路径
/wiki/Special:BookSources/0-8018-1841-9
有一个例外。我想保留带有第二个冒号的那些 if 它后面跟着一个下划线:
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 question and this one) 是 ^[^:]*[:]*.*(/wiki/)[^:]+$
,它解决了我需求的第一部分,但没有解决第二部分。
我如何解释冒号后跟下划线的特殊情况?
消极的前瞻可能在这里最有意义:
^https?://(?!.*:[^_]).*wiki.*
请注意 /wiki/Special:BookSources/0-8018-1841-9
严格来说不是 URL 因为没有协议。相反,它是一条路径。您可能需要稍微修改一下我上面写的内容,但否定前瞻是解决您问题的简单方法。
在处理以各种形式、不同方案或没有域锚的 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
在这个例子中,任何语句都为你想要忽略的 urls 返回 true。如果你想让这个例子更实用一点,你也可以使用正则表达式进行过滤。
>>> any(re.search(':[^_]',i) for i in url.parts[1:])
True
>>> any(re.search(':[^_]',i) for i in url2.parts[1:])
False
如果您正在使用这些 url 执行任何请求,我建议您试试 urlpath 库。它结合了 pathlib 的灵活性、功能性 urllib.parse,并根据要求构建了它。
>>> url.get()
<Response [200]>
我正在尝试匹配不包含第二个冒号(在协议中的冒号之后,例如 http(s)://
)的 URL 或相对路径。
我想拒绝
形式的 URLhttps://en.wikipedia.org/wiki/Special:BookSources/0-8018-1841-9
或形式的路径
/wiki/Special:BookSources/0-8018-1841-9
有一个例外。我想保留带有第二个冒号的那些 if 它后面跟着一个下划线:
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 question and this one) 是 ^[^:]*[:]*.*(/wiki/)[^:]+$
,它解决了我需求的第一部分,但没有解决第二部分。
我如何解释冒号后跟下划线的特殊情况?
消极的前瞻可能在这里最有意义:
^https?://(?!.*:[^_]).*wiki.*
请注意 /wiki/Special:BookSources/0-8018-1841-9
严格来说不是 URL 因为没有协议。相反,它是一条路径。您可能需要稍微修改一下我上面写的内容,但否定前瞻是解决您问题的简单方法。
在处理以各种形式、不同方案或没有域锚的 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
在这个例子中,任何语句都为你想要忽略的 urls 返回 true。如果你想让这个例子更实用一点,你也可以使用正则表达式进行过滤。
>>> any(re.search(':[^_]',i) for i in url.parts[1:])
True
>>> any(re.search(':[^_]',i) for i in url2.parts[1:])
False
如果您正在使用这些 url 执行任何请求,我建议您试试 urlpath 库。它结合了 pathlib 的灵活性、功能性 urllib.parse,并根据要求构建了它。
>>> url.get()
<Response [200]>