2011-04-11 13 views
49

Próbuję znaleźć co 10 cyfr serii liczb w większej serii liczb przy użyciu ponownie w Pythonie 2.6.Python regex znaleźć wszystkie pokrywające się mecze?

Z łatwością łapię nie nakładające się mecze, ale chcę każdy mecz w serii liczbowej. Na przykład.

w „123456789123456789”

powinienem dostać następującą listę:

[1234567891,2345678912,3456789123,4567891234,5678912345,6789123456,7891234567,8912345678,9123456789] 

mam znaleźć odniesienia do „uprzedzona”, ale przykłady widziałem pokazują tylko pary liczb raczej niż większe grupy i nie mogłem ich przekonwertować poza dwie cyfry.

+6

Przedstawione rozwiązania nie będą działać, gdy nakładające się mecze rozpoczną się w tym samym punkcie, np. Dopasowanie "a | ab | Czy istnieje rozwiązanie, które nie wymaga wielokrotnego wywoływania match(), ręcznie śledząc granicę "końca"? –

+0

@ VítorDeAraújo: nakładające się wyrażenia regularne, takie jak '(a | ab | abc)", można ogólnie przepisać jako niepokrywające się z zagnieżdżonymi grupami przechwytywania, np. '(a (b (c)?)?)?', gdzie ignorujemy wszystkie poza zewnętrzną (tj. lewą) grupą przechwytującą podczas rozpakowywania dopasowania; wprawdzie jest to nieco bolesne i mniej czytelne. Będzie to również bardziej efektywne wyrażenie regularne do dopasowania. – smci

Odpowiedz

96
import re 
s = "123456789123456789" 
matches = re.finditer(r'(?=(\d{10}))',s) 
results = [int(match.group(1)) for match in matches] 
# results: 
# [1234567891, 
# 2345678912, 
# 3456789123, 
# 4567891234, 
# 5678912345, 
# 6789123456, 
# 7891234567, 
# 8912345678, 
# 9123456789] 
+1

Jesteście sir, są fantastyczni. Dzięki! – danspants

+1

Moja odpowiedź jest co najmniej 2 razy szybsza od tej. Ale to rozwiązanie jest trudne, podniosłem to. – eyquem

+0

ktoś może wyjaśnić, dlaczego to działa? – qkhhly

18

Uwielbiam wyrazy regularne, ale nie są one tutaj potrzebne.

Wystarczy

s = "123456789123456789" 

n = 10 
li = [ s[i:i+n] for i in xrange(len(s)-n+1) ] 
print '\n'.join(li) 

wynik

1234567891 
2345678912 
3456789123 
4567891234 
5678912345 
6789123456 
7891234567 
8912345678 
9123456789 
+0

Regeksy nie są tutaj potrzebne tylko dlatego, że stosujesz specjalną wiedzę "w większej liczbie numerów", więc znasz już każdą pozycję '0 <= i smci

49

Można również spróbować użyć new Python regex module, które obsługuje nakładające się mecze.

>>> import regex as re 
>>> s = "123456789123456789" 
>>> matches = re.findall(r'\d{10}', s, overlapped=True) 
>>> for match in matches: print match 
... 
1234567891 
2345678912 
3456789123 
4567891234 
5678912345 
6789123456 
7891234567 
8912345678 
9123456789 
+1

To bardzo pomogło, dzięki! – VedTopkar