2010-06-28 82 views
4

这是一个涉及Python中的条件正则表达式的问题:Python的条件正则表达式

我想​​匹配字符串

match(1)="a" 
match(2)="b" 
match(3)="c" 

而且还匹配字符串" a"

match(1)="a" 
match(2)="" 
match(3)="" 

以下代码几乎是这样做的,问题是在第一种情况下match(1)="a" bu t在第二种情况下,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的)

回答

5

也许......:

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 ...但我只是猜测你不是想在这种情况下匹配......? )

+0

你说得对 - 这是仅有的两个案例。正如我所希望的那样工作。关键是有“?”在匹配组(\ w?)内部,以便匹配该字母,或者不匹配任何内容。谢谢! – Mike 2010-06-28 16:14:23

+0

@Mike,不客气 - 总是乐于帮忙! – 2010-06-28 16:43:47

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