Python 条件正则表达式
这是一个关于在Python中使用条件正则表达式的问题:
我想要匹配字符串 "abc"
,并且
match(1)="a"
match(2)="b"
match(3)="c"
也想要匹配字符串 " a"
,并且
match(1)="a"
match(2)=""
match(3)=""
下面的代码几乎可以做到这一点,但问题是,在第一个情况下 match(1)="a"
,而在第二个情况下,match(4)="a"
(而不是我想要的 match(1)
)。
实际上,如果你用 for g in re.search(myre,teststring2).groups():
来遍历所有的组,你会得到6个组(而不是预期的3个)。
import re
import sys
teststring1 = "abc"
teststring2 = " a"
myre = '^(?=(\w)(\w)(\w))|(?=\s{2}(\w)()())'
if re.search(myre,teststring1):
print re.search(myre,teststring1).group(1)
if re.search(myre,teststring2):
print re.search(myre,teststring2).group(1)
有什么想法吗?(注意这是针对Python 2.5的)
3 个回答
1
myre = '^(?=\s{0,2}(\w)(?:(\w)(\w))?)'
这个方法可以处理你提到的两种情况,效果也正是你想要的,但它不一定是一个通用的解决方案。感觉你提出的是一个简单的问题,但它实际上代表了一个更复杂的问题。
要找到一个通用的解决方案非常困难,因为后面的元素处理依赖于前面的元素处理,反之亦然。举个例子,如果你有完整的 abc
,那么开头的空格就不应该存在。如果开头有空格,那么你只能找到 a
。
在我看来,处理这个问题的最好方法还是你最开始用的 |
结构。你可以在匹配之后加一些代码,把匹配到的部分提取到一个数组里,然后按照你喜欢的方式排列。
关于分组的规则是:所有没有紧接着 ?:
的开括号都会形成一个分组。这个分组可能是空的,因为它实际上没有匹配到任何东西,但它仍然会存在。
3
在这个表达式中,每个捕获组都有自己的索引。你可以试试这个:
r = re.compile("^\s*(\w)(\w)?(\w)?$")
abc -> ('a', 'b', 'c')
a -> ('a', None, None)
下面来简单解释一下:
^ // anchored at the beginning
\s* // Any number of spaces to start with
(\w) // capture the first letter, which is required
(\w)? // capture the second letter, which is optional
(\w)? // capture the third letter, which is optional
$ // anchored at the end
9
也许...:
import re
import sys
teststring1 = "abc"
teststring2 = " a"
myre = '^\s{0,2}(\w)(\w?)(\w?)$'
if re.search(myre,teststring1):
print re.search(myre,teststring1).group(1)
if re.search(myre,teststring2):
print re.search(myre,teststring2).group(1)
这样做确实能在你想要的情况下都得到 a
,但是在你没有展示的其他情况下,可能就不太符合你的要求了(比如前面没有空格,或者后面有空格 并且 多于一个字母,这样匹配到的字符串总长度就会 != 3
... 不过我只是猜测你 不 想在这种情况下得到匹配...?)