2016-01-03 11 views
9

Chciałbym znaleźć wszystkie naprzemienne cyfry w ciągu za pomocą wyrażeń regularnych. Cyfra naprzemienna definiowana jest jako dwie równe cyfry mające cyfrę pomiędzy; na przykład 1212 zawiera 2 warianty (121 i 212), a 1111 zawiera również 2 warianty (111 i 111). Mam następujący kod regularnego wyrażenia:Znajdowanie wszystkich wystąpień naprzemiennych cyfr za pomocą wyrażeń regularnych

s = "1212" 
re.findall(r'(\d)(?:\d)(\1)+', s) 

Działa to w przypadku ciągów takich jak "121656", ale nie "1212". Jest to problem związany z nakładającymi się meczami, które myślę. Jak sobie z tym poradzić?

+0

Szczególna odpowiedź udzielona przez @vks; zobacz także odpowiedź na podobne pytanie @ http://stackoverflow.com/a/320478/43774. – rivy

Odpowiedz

7
(?=((\d)\d\2)) 

Użyj lookahead, aby uzyskać wszystkie nakładające się mecze. Użyj re.findall i zdobądź pierwszy element z krotki. Zobacz prezentację:

https://regex101.com/r/fM9lY3/54

+0

Aby dopasować przechwycenia jego pytania, użyłbym '(\ d) (? = (?: \ D) (\ 1))'. – rivy

+0

@Roy Chyba chce "121 i 212" zamiast "1 lub 2" – vks

2

Można użyć uprzedzona, aby umożliwić nakładających się na mecz:

r'(\d)(?=(\d)\1)' 

zrekonstruować pełne mecze z tego:

matches = re.findall(r'(\d)(?=(\d)\1)', s) 
[a + b + a for a, b in matches] 

Ponadto, aby uniknąć innych Numery uniksowe, takie jak 1, są porównywane (zakładając, że ich nie chcesz), zamiast należy użyć cyfr [0-9].

3

Z regex module nie trzeba używać trick aby uzyskać pokrywające mecze ponieważ tam flagę, aby uzyskać je:

import regex 
res = [x.group(0) for x in regex.finditer(r'(\d)\d\1', s, overlapped=True)] 

jeśli ów zawiera tylko cyfry, można to zrobić za:

res = [s[i-2:i+1] for i in range(2, len(s)) if s[i]==s[i-2]] 
2

non podejście regex jeśli łańcuch składa się z zaledwie cyfr:

from itertools import islice as isl, izip 

s = "121231132124123" 
out = [a + b + c for a, b, c in zip(isl(s, 0, None), isl(s, 1, None), isl(s, 2, None)) if a == c] 

Wyjście:

['121', '212', '212'] 

To jest naprawdę przyjemne trochę szybciej niż podejście regex.

Powiązane problemy