在Python

时间:2017-01-03 23:05:05

标签: python regex

我已多次浏览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 到目前为止的答案是有帮助的,但我认为我没有足够清楚地解释我的需要。

简而言之,我想要一个匹配foobar(完整)或foo bazbar 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匹配或根本不匹配?

3 个答案:

答案 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$仅匹配整个字符串。