[英]python regex how to capture all groups that may be optional?
minutes_pattern = re.compile(
r"""
(?:(?P<hours>\d+)H)?
(?:(?P<minutes>\d+)M)?
(?:(?P<seconds>\d+)S)?
""",
re.VERBOSE,
)
我試圖捕捉所有的小時、分鍾、秒。 但是,這些可能存在也可能不存在: 示例:
PT30H20M10S
PT20M10S
PT20M
PT3010S
PT30H
我在想(?:(?P<hours>\d+)H)?
說:
但是這個編譯沒有捕獲任何 3 個組。 請幫忙
regex = minutes_pattern.search(duration)
print(regex.groups())
這只返回無
(None, None, None)
理想情況下,這將顯示(對於第一個示例):
group hours: 30
group minutes: 20
group seconds: 10
對於第二個示例:
group hours: None
group minutes: 20
group seconds: 10
問題是您的正則表達式成功匹配一個空字符串,因此當您使用.search
搜索第一個匹配項時,第一個匹配項出現在索引 0 處,長度為 0:
>>> minutes_pattern.search(duration)
<_sre.SRE_Match object; span=(0, 0), match=''>
解決此問題的最簡單方法是在正則表達式的開頭包含字母PT
,因為這些字母始終存在於您的輸入字符串中,並且它們防止正則表達式返回空匹配:
>>> minutes_pattern = re.compile(r"PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?")
>>> minutes_pattern.search(duration)
<_sre.SRE_Match object; span=(0, 11), match='PT30H20M10S'>
>>> minutes_pattern.search(duration).groups()
('30', '20', '10')
或者,如果您不想在您的正則表達式中包含PT
(也許其他一些輸入不會包含該前綴),您可以使用.findall
而不是.search
,然后過濾列表以查找“非平凡”匹配:
>>> minutes_pattern = re.compile(r"(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?")
>>> minutes_pattern.findall(duration)
[('', '', ''), ('', '', ''), ('30', '20', '10'), ('', '', '')]
>>> next(filter(any, minutes_pattern.findall(duration)), None)
('30', '20', '10')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.