2011-12-15 109 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(','))