重复序列的正则表达式

时间:2011-12-15 07:39:57

标签: python regex

我想匹配由逗号分隔的三个字母的字母序列(只允许使用字母'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

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

7 个答案:

答案 0 :(得分:10)

尝试以下正则表达式:

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

^...$从字母开头到字符串结束 [...]其中一个给定的字符
...{3}三次前的短语 (...)* 0到括号中的字符的n倍

答案 1 :(得分:4)

你要求它用正则表达式找到的是“至少三个字母a,b,c” - 这就是“+”给你的东西。无论之后是什么,对正则表达式来说并不重要。您可能希望包含“$”,这意味着“行尾”,以确保该行必须包含允许的三元组。但是在当前形式中,你的正则表达式还要求最后一个三元组以逗号结尾,所以你应该明确地编写它不是这样的代码。 试试这个:

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

这会找到任意数量的允许三元组,后跟逗号(可能为零),然后是三元组,不带逗号,然后是行尾。

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

答案 2 :(得分: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"

答案 3 :(得分:1)

自正则表达式

以来,您的结果并不令人惊讶
([abc][abc][abc],)+

尝试匹配字符串中包含三个字符[abc]后跟逗号一次或多次任何地方的字符串。所以最重要的部分是确保字符串中没有其他内容 - 正如scessor所建议的那样,将^(字符串的开头)和$(字符串的结尾)添加到正则表达式中。 / p>

答案 4 :(得分:1)

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

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

答案 5 :(得分: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

答案 6 :(得分: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表示:字符串的结尾。它的存在迫使比赛直到弦的最后

顺便说一句,我也喜欢Sonya的形式,更清楚:

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