我在Python中编写一个带有可选部分的正则表达式。我注意到有时这些可选部分与None匹配,有时它们与空字符串匹配,或者至少从我的测试中看起来是这样。我想了解为什么以及如何将正则表达式修改为一致或另一种。
def artifactory_url():
test_input = [
"https://www.domain.com/artifactory/my-root",
"https://www.domain.com/artifactory",
"https://www.domain.com/artifactory/my-root/platform",
"http://www.domain.com/artifactory/my-root/platform",
"http://www.domain.com/artifactory/my-root/platform/Daily Gold Reserve/WW3/bin",
"single-dir",
"double/dir",
]
import re
re_splitroot = re.compile('(?P<drive>https?://.+/artifactory)?/?(?:(?P<root>[^/]+)/?)?(?P<remainder>.*)?/?', re.IGNORECASE)
for i in test_input:
dprint (i)
m = re_splitroot.match(i)
if m:
dprint (" True:\n drive=%s\n root=%s\n remainder=%s" % (m.group('drive'), m.group('root'), m.group('remainder')), 0)
else:
dprint (" False")
此测试功能产生以下输出。
https://www.domain.com/artifactory/my-root
True:
drive=https://www.domain.com/artifactory
root=my-root
remainder=
https://www.domain.com/artifactory
True:
drive=https://www.domain.com/artifactory
root=None
remainder=
https://www.domain.com/artifactory/my-root/platform
True:
drive=https://www.domain.com/artifactory
root=my-root
remainder=platform
http://www.domain.com/artifactory/my-root/platform
True:
drive=http://www.domain.com/artifactory
root=my-root
remainder=platform
http://www.domain.com/artifactory/my-root/platform/Daily Gold Reserve/WW3/bin
True:
drive=http://www.domain.com/artifactory
root=my-root
remainder=platform/Daily Gold Reserve/WW3/bin
single-dir
True:
drive=None
root=single-dir
remainder=
double/dir
True:
drive=None
root=double
remainder=dir
答案 0 :(得分:1)
你的第一部分:
(?P<drive>https?://.+/artifactory)?
应匹配任何http://.../artifactory
(如果存在),但尾随?
表示如果找不到,则整个捕获的组将为空。
您可能想要使用
(?P<drive>(?:https?://.+/artifactory)?)
这将使该部分捕获&#34;空虚&#34;如果找不到该匹配,但不会将其保留为NULL。
你的第二部分:
(?:(?P<root>[^/]+)\?)?
尝试捕获不是/
的任何内容,但其中包含的(?:...)
群组有一个尾随?
,这也是可选/空的。如果您更换(?P<...>)
和(?:...)
组,您的结果将与第一组更加一致。
最后,你的
(?P<remainder.*)?
组是多余的:它可以仅使用.*
捕获0或更多剩余文本,但您也可以选择(?
)。您可以删除?
,并留下空匹配。
您的示例可以在this page上找到,我建议的更改可以在this one上找到,如果您想查看它们是否会产生任何不同的结果。