我已多次浏览HOWTO和re
模块文档,我仍然对Python正则表达式中的可选性和分组交互方式感到困惑。我想要的是匹配组内的所有内容,或者根本不匹配,但我发现子字符串是匹配的。这是一个最小的例子:
>> re.compile(r"(test)?").search("tes")
<_sre.SRE_MATCH at 0xBlahBlah>
我希望不匹配,因为我将整个字符串test
标记为可选。什么(文档的一部分)我不理解?
与我真正感兴趣的问题相近的问题版本如下:
>> re.compile(r"(distance|mileage)(\sbetween)?").search("distancebetween")
<_sre.SRE_MATCH at 0xBlahblah>
为什么这个空格不被强制匹配?
编辑2017-01-04 到目前为止的答案是有帮助的,但我认为我没有足够清楚地解释我的需要。
简而言之,我想要一个匹配foo
或bar
(完整)或foo baz
或bar baz
(完整)的正则表达式,而不是其他内容。
>> m = re.compile("(foo|bar)(\sbaz)?")
>> m.search("foo ba")
<_sre.SRE_Match as 0xBlahblah>
>> m.search("foo ba").span()
(0, 3)
所以我发现它正在发生的事情是它在foo
上匹配,然后没有关心下游的事情。如何才使其仅与baz
匹配或根本不匹配?
答案 0 :(得分:4)
让我们看看匹配的内容:
import re
m = re.compile(r"(test)?").search("tes")
m.span()
# have (0, 0)
它是空字符串。为什么呢?
因为?
在这里表示零或一次(就像{0, 1}
)。所以第一组可以匹配字符串test
或空字符串(我们有)。
以下是docs:
的引用
'?'
使得到的RE匹配前面RE的0或1次重复。 AB?将匹配'a'或'ab'。
答案 1 :(得分:1)
对于您所描述的内容,我不认为您想要使用可选匹配。我认为你想要的是正确的正则表达式,但没有?
。
第一个例子:
>>> re.compile(r"(test)").search("tes")
>>> re.compile(r"(test)").search("test")
<_sre.SRE_Match object at 0x104c64210>
>>> re.compile(r"(test)").search("testing")
<_sre.SRE_Match object at 0x104c64198>
对于你的第二个例子:
>>> re.compile(r"(distance|mileage)(\sbetween)").search("distancebetween")
>>> re.compile(r"(distance|mileage)(\sbetween)").search("distance between")
<_sre.SRE_Match object at 0x104bf5608>
>>> re.compile(r"(distance|mileage)(\sbetween)").search("distance ")
答案 2 :(得分:1)
在这两种情况下都使用 在第二个中, 这些都不是整个字符串,因此可以在之前或之后进行测试。否则,如果您只想要开始,则需要?
,你说你要小组出现0或1次。因此,在"(test)?"
中 匹配“test”与不匹配,或为空字符串,这将是字符串的第一部分。< / p>
"(distance|mileage)(\sbetween)?"
你有四个匹配的“距离”,“里程”或“距离”或“里程之间”。^regex
,或regex$
仅匹配结尾,或最后^regex$
仅匹配整个字符串。