【发布时间】:2019-11-15 15:41:07
【问题描述】:
问题:
我正在寻找一种方法来匹配给定行中的某些标识符
以某些词开头。 ID 包括
字符,可能后跟数字,然后是破折号,然后是一些
更多的数字。一个 ID 应该只匹配
起始词是以下之一:关闭、修复、解决。如果一个
行包含多个 ID,它们将由
字符串and。任意数量的 ID 可以出现在一个
行。
示例测试字符串:
Closes PD-1 # Match: PD-1
Related to PD-2 # No match, line doesn't start with an allowed word
Closes
NPD-1 # No match, as the identifier is in a new line
Fixes PD-21 and PD-22 # Match: PD-21, PD-22
Closes PD-31, also PD-32 and PD-33 # Match: PD-31 - the rest is not captured because of ", also"
Resolves PD4-41 and PD4-42 and PD4-43 and PD4-44 # Match: PD4-41, PD4-42, PD4-43, PD4-44
Resolves something related to N-2 # No match, the identifier is not directly after 'Resolves'
我尝试了什么:
使用正则表达式来获取所有匹配项,我总是在某些方面做得不够。例如。我试过的正则表达式之一是这样的:
^(?:Closes|Fixes|Resolves) (\w+-\d+)(?:(?: and )(\w+-\d+))*
- 我打算在线路需要的地方设置一个非捕获组
以允许的单词之一开头,后跟一个空格:
^(?:Closes|Fixes|Resolves) - 那么至少需要一个ID跟在起始词后面,
我打算捕获:
(\w+-\d+) - 最后,零个或多个 ID 可以跟随第一个,它们是
由字符串
and分隔,但我只想捕获 这里是 ID,而不是分隔符:(?:(?: and )(\w+-\d+))*
这个正则表达式在 python 中的结果:
test_string = """
Closes PD-1 # Match: PD-1
Related to PD-2 # No match, line doesn't start with an allowed word
Closes
NPD-1 # No match, as the identifier is in a new line
Fixes PD-21 and PD-22 # Match: PD-21, PD-22
Closes PD-31, also PD-32 and PD-33 # Match: PD-31 - the rest is not captured because of ", also"
Resolves PD4-41 and PD4-42 and PD4-43 and PD4-44 # Match: PD4-41, PD4-42, PD4-43, PD4-44
Resolves something related to N-2 # No match, the identifier is not directly after 'Resolves'
"""
ids = []
for match in re.findall("^(?:Closes|Fixes|Resolves) (\w+-\d+)(?:(?: and )(\w+-\d+))*", test_string, re.M):
for group in match:
if group:
ids.append(group)
print(ids)
['PD-1', 'PD-21', 'PD-22', 'PD-31', 'PD4-41', 'PD4-44']
Also, here is the result on regex101.com。如果在第一个 ID 之后有多个 ID,不幸的是它只会捕获最后一个匹配项,而不是所有匹配项。我读到重复捕获组只会捕获最后一次迭代,我应该在重复组周围放置一个捕获组以捕获所有迭代,但我无法让它工作。
总结:
有没有正则表达式的解决方案,类似于我尝试的方法,但它捕获了所有出现的 ID?或者有没有更好的方法来解析这个字符串的 ID,使用 Python?
【问题讨论】:
标签: python regex python-3.x