2011-12-15 106 views
3

我想匹配由逗号分隔的三个字符的字母序列(只允许使用字母'a','b','c')(最后一个组不以逗号结尾)。重复序列的正则表达式

例子:

abc,bca,cbb 
ccc,abc,aab,baa 
bcb 

我已经写了下面的正则表达式:

re.match('([abc][abc][abc],)+', "abc,defx,df") 

但是它不能正常工作,因为上面的例子:

>>> print bool(re.match('([abc][abc][abc],)+', "abc,defx,df")) # defx in second group 
True 
>>> print bool(re.match('([abc][abc][abc],)+', "axc,defx,df")) # 'x' in first group 
False 

似乎只检查第一组三个字母,但它忽略了其余部分。如何正确编写这个正则表达式?

回答

8

尝试以下的正则表达式:

^[abc]{3}(,[abc]{3})*$ 

^...$从开始到字符串
[...]给定字符中的一个
...{3}三个时间短语的结束
(...)* 0至n次前括号内的字符

1

您的结果并不令人惊讶,因为正则表达式

([abc][abc][abc],)+ 

尝试匹配包含[abc]三个字符后面跟随逗号一个或多个次所述串中的任意位置的字符串。因此,最重要的部分是确保字符串中没有其他内容 - 正如处理者向正则表达式添加^(字符串的开始)和$(字符串的末尾)所示。

3

你要求它用你的正则表达式找到的是“至少有三个字母a,b,c” - 这就是“+”给你的。随后的任何内容对于正则表达式无关紧要。您可能需要包含“$”,即“行尾”,以确保该行必须全部由允许的三元组组成。然而,在目前的形式中,你的正则表达式也会要求最后的三重结尾用逗号,所以你应该明确地编码它不是这样。 尝试此:

re.match('([abc][abc][abc],)*([abc][abc][abc])$' 

此发现的任何数量的允许的三元组跟随逗号(也许零),则三没有逗号,则该行的端部的。

编辑:包括“^”(字符串的开头)符号不是必需的,因为match方法只在字符串的开始处检查匹配。

+0

你解释清楚,正则表达式将需要在开始和结束锚,但不包括``^在您的解决方案。 – stema 2011-12-15 08:01:20

+0

糟糕!谢谢,我会编辑它。 – Sonya 2011-12-15 08:07:39

2

您需要迭代找到的值的序列。

data_string = "abc,bca,df" 

imatch = re.finditer(r'(?P<value>[abc]{3})(,|$)', data_string) 

for match in imatch: 
    print match.group('value') 

所以检查正则表达式是否匹配字符串模式将

data_string = "abc,bca,df" 

match = re.match(r'^([abc]{3}(,|$))+', data_string) 

if match: 
    print "data string is correct" 
0

另一种不使用正则表达式(虽然蛮力方式):如果你的目标是

>>> def matcher(x): 
     total = ["".join(p) for p in itertools.product(('a','b','c'),repeat=3)] 
      for i in x.split(','): 
       if i not in total: 
        return False 
     return True 

>>> matcher("abc,bca,aaa") 
    True 
>>> matcher("abc,bca,xyz") 
    False 
>>> matcher("abc,aaa,bb") 
    False 
0

验证字符串是由字母a,b和c的三元组组成的:

for ss in ("abc,bbc,abb,baa,bbb", 
      "acc", 
      "abc,bbc,abb,bXa,bbb", 
      "abc,bbc,ab,baa,bbb"): 
    print ss,' ',bool(re.match('([abc]{3},?)+\Z',ss)) 

结果

abc,bbc,abb,baa,bbb  True 
acc  True 
abc,bbc,abb,bXa,bbb  False 
abc,bbc,ab,baa,bbb  False 

\Z指:字符串的末尾。它的存在迫使对手是直到字符串

顺便说的尽头,我喜欢索尼娅的形式也一样,在某种程度上,它是清晰的:

bool(re.match('([abc]{3},)*[abc]{3}\Z',ss)) 
0

强制性“你不吨需要一个正则表达式”的解决方案:

all(letter in 'abc,' for letter in data) and all(len(item) == 3 for item in data.split(','))