说我有两种类型的字符串:
str1 = 'NUM-140 A Thing: Foobar Analysis NUM-140'
str2 = 'NUM-140 Foobar Analysis NUM-140'
对于这两个,我想匹配'Foobar'
(可能是任何东西)。我尝试过以下方法:
m = re.compile('((?<=Thing: ).+(?= Analysis))|((?<=\d ).+(?= Analysis))')
ind1 = m.search(str1).span()
match1 = str1[ind1[0]:ind1[1]]
ind2 = m.search(str2).span()
match2 = str2[ind2[0]:ind2[1]]
然而,match1出现在'A Thing: Foobar'
,这似乎是第二种模式的匹配,而不是第一种模式。单独应用(模式1到str1
和模式2到str2
,没有|
),两个模式都匹配'Foobar'
。我预计这会在第一个模式匹配时停止。这似乎并非如此。我错过了什么?
答案 0 :(得分:1)
根据文件,
扫描目标字符串时,RE由&#39; |&#39;分隔。从左到右尝试。当一个模式完全匹配时,接受该分支。这意味着一旦A匹配,B将不会被进一步测试,即使它会产生更长的整体匹配。换句话说,&#39; |&#39;操作员从不贪心。
但行为似乎有所不同:
import re
THING = r'(?<=Thing: )(?P<THING>.+)(?= Analysis)'
NUM = r'(?<=\d )(?P<NUM>.+)(?= Analysis)'
MIXED = THING + '|' + NUM
str1 = 'NUM-140 A Thing: Foobar Analysis NUM-140'
str2 = 'NUM-140 Foobar Analysis NUM-140'
print(re.match(THING, str1))
# <... match='Foobar'>
print(re.match(NUM, str1))
# <... match='A Thing: Foobar'>
print(re.match(MIXED, str1))
# <... match='A Thing: Foobar'>
我们希望因为THING匹配&#39; Foobar&#39;,MIXED模式将获得&#39; Foobar&#39;并退出搜索。 (根据文件)
因为它没有按照文档记录的方式工作,所以解决方案必须依赖于Python的or
短路:
print(re.search(THING, str1) or re.search(NUM, str1))
# <_sre.SRE_Match object; span=(17, 23), match='Foobar'>
print(re.search(THING, str2) or re.search(NUM, str2))
# <_sre.SRE_Match object; span=(8, 14), match='Foobar'>
答案 1 :(得分:0)
如果您使用命名组,例如(?P<name>...)
,您将能够更轻松地进行调试。但请注意span的文档。
https://docs.python.org/2/library/re.html#re.MatchObject.span
span([group])对于MatchObject m,返回2元组(m.start(组), m.end(组))。请注意,如果组没有参与比赛, 这是(-1,-1)。组默认为零,整个匹配。
你没有传递组号。
为什么你还在使用span?只需使用m.search(str1).groups()
或类似的