2013-07-10 10 views
6

Chcę znaleźć słowa, które mają kolejne pary liter za pomocą wyrażenia regularnego. Znam tylko dla jednej pary z rzędu, jak zoo (oo), puzzle (zz), aranżacja (rr), można to osiągnąć przez '(\w){2}'. Ale jak opython: jak znaleźć kolejne pary liter według regex?

  • dwoma kolejnymi parami: komisja (ttee)
  • trzech kolejnych parach księgowy (ookkee)

edit:

  • '(\w){2}' jest rzeczywiście źle , znajduje dwie dowolne litery zamiast podwójnej pary liter.
  • Moim zamiarem jest znaleźć słów, które mają pary liter, a nie pary.
  • "Kolejny" oznacza, że ​​nie ma innej litery między parami liter.
+1

możliwe duplikat [Wróć na rozmowę z podwójnymi kolejnymi literami] (http://stackoverflow.com/ pytania/9593622/return-words-with-double-konsekute-letters) – ChrisGuest

+0

'\ w {2}' odnosi się tylko do dwóch liter, 'ab', 'cc' są zarówno OK. – zhangyangyu

+0

faktycznie, '(\ w) {2}' dopasowuje dowolne 2 kolejne litery, pasujące lub nie. Dopasuje "zo" do "zoo". –

Odpowiedz

4

Można użyć tego wzoru:

[a-z]*([a-z])\1([a-z])\2[a-z]* 

pomysł jest użyć odwołania wstecznego \1 i \2, które odnoszą się do grup przechwytywania.

Pamiętaj, że (\w){2} dopasowuje dwa znaki słowne, ale nie to samo.

+0

To działa! Aby znaleźć słowa z trzech kolejnych par liter, wyrażenie regularne będzie miało postać "[az] * ([az]) \ 1 ([az]) \ 2 [az] * ([az]) \ 3 [az] *", ale nie tylko znajduje ** księgowego **, ale także ** zieleń **, która łamie regułę "z rzędu". Jak tego uniknąć? –

+1

@Teacode: nie dla trzech musisz napisać: '[a-z] * ([a-z]) \ 1 ([a-z]) \ 2 ([a-z]) \ 3 [a-z] *' –

+0

Masz rację! Dziękuję Ci. Wstydź się za mój błąd, jestem totalnym początkującym z regex. –

14

Zastosowanie re.finditer

>>> [m.group() for m in re.finditer(r'((\w)\2)+', 'zoo')] 
['oo'] 
>>> [m.group() for m in re.finditer(r'((\w)\2)+', 'arrange')] 
['rr'] 
>>> [m.group() for m in re.finditer(r'((\w)\2)+', 'committee')] 
['mm', 'ttee'] 
>>> [m.group() for m in re.finditer(r'((\w)\2)+', 'bookkeeper')] 
['ookkee'] 

Sprawdź, czy ciąg zawierać kolejne pary:

>>> bool(re.search(r'((\w)\2){2}', 'zoo')) 
False 
>>> bool(re.search(r'((\w)\2){2}', 'arrange')) 
False 
>>> bool(re.search(r'((\w)\2){2}', 'committee')) 
True 
>>> bool(re.search(r'((\w)\2){2}', 'bookkeeper')) 
True 

Można również użyć następujących, przechwytywanie (?:) wersja:

(?:(\w)\1){2} 
+0

Myślę, że moje pytanie było źle sformułowane. Zamiast znajdować pary liter od słowa, to co naprawdę chcę zrobić, to znaleźć słowa (z listy słów), które mają kolejne pary liter. –

+0

@Teacode, zaktualizowałem kod. – falsetru

+0

Dziękuję. Teraz rozumiem. '((\ w) \ 2) {3}' jest równoważne '(\ w) \ 1 (\ w) \ 2 (\ w) \ 3' i bardziej eleganckiemu! –

0

Bo wspomniałem, że chcesz przetestować z listy, odpowiedziałem jako taki. Korzystanie falsetru za odpowiedź:

newlist = [] 

for word in list: 
    if [m.group() for m in re.finditer(r'((\w)\2)+', word)] != []: 
    newlist.append(word) 

print newlist 
0

Do wykrywania 2- lub-More kolejnymi literami regex staje: (\w)\1+