2010-04-24 13 views
23

W moim fragmencie poniżej, grupa non-przechwytywanie "(?:aaa)" powinny być ignorowane w pasującym rezultacie więc wynik powinien być tylko "_bbb".
Jednak otrzymuję "aaa_bbb" w dopasowanym wyniku; tylko gdy określę grupę (2), pokazuje ona "_bbb".Dlaczego grupa wyrażenie regularne za „non-przechwytywanie” nie działa

import re 

string1 = "aaa_bbb" 
print(re.match(r"(?:aaa)(_bbb)", string1).group()) 

>>> aaa_bbb 
+1

fajne, dziękuję za edycję i odpowiedzi wskazujące na koncepcję niezapisywania grupy –

Odpowiedz

25

group() i group(0) zwróci cały mecz. Kolejne grupy są rzeczywistymi grupami przechwytywania.

>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(0)) 
aaa_bbb 
>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(1)) 
_bbb 
>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(2)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
IndexError: no such group 
1

Spróbuj:

print(re.match(r"(?:aaa)(_bbb)", string1).group(1)) 

group() jest taka sama jak group(0) i Grupa 0 jest zawsze obecny i jest to cały RE mecz.

2

TFM:

class re.MatchObject

group([group1, ...])

zwraca jeden lub więcej podgrup meczu. Jeśli istnieje jeden argument, wynikiem jest pojedynczy ciąg; jeśli istnieje wiele argumentów, wynikiem jest krotka z jedną pozycją na argument. Bez argumentów domyślnie grupa 1 przyjmuje wartość zero (zwracane jest całe dopasowanie). Jeśli argument groupN wynosi zero, odpowiednią wartością zwracaną jest cały pasujący ciąg.

0

Musisz podać group(1), aby uzyskać tylko część przechwyconą przez nawias (w tym przypadku _bbb).

group() bez parametrów spowoduje, że cały ciąg zostanie uzupełniony pełnym dopasowaniem wyrażenia regularnego, niezależnie od tego, czy niektóre jego części zostały dodatkowo przechwycone przez nawias, czy nie.

+0

dzięki za wyjaśnienie szczegółów :) –

55

Myślę, że nie rozumiesz pojęcia "grupy niezapisującej". Tekst dopasowany przez grupę niezapisującą nadal staje się częścią ogólnego dopasowania do wyrażenia regularnego.

Zarówno wyrażenie (?:aaa)(_bbb), jak i wyrażenie regex (aaa)(_bbb) zwracają aaa_bbb jako całkowite dopasowanie. Różnica polega na tym, że pierwsze wyrażenie ma jedną grupę przechwytującą, która zwraca _bbb jako dopasowanie, podczas gdy drugie wyrażenie ma dwie grupy przechwytujące, które zwracają aaa i _bbb jako odpowiadające im dopasowania. W swoim kodzie Pythona, aby uzyskać _bbb, musisz użyć group(1) z pierwszym wyrażeń regularnych i group(2) z drugim wyrażeniem regularnym.

Główną zaletą grup niezapisujących jest możliwość dodania ich do wyrażeń regularnych bez naruszania numeracji grup przechwytywania w wyrażeniu regularnym. Oferują również (nieco) lepszą wydajność, ponieważ silnik regex nie musi śledzić tekstu pasującego do grup, które nie przechwytują.

Jeśli naprawdę chcesz wykluczyć aaa z ogólnego dopasowania do wyrażenia regularnego, musisz użyć lookaround. W tym przypadku pozytywny lookbehind rozwiązuje problem: (?<=aaa)_bbb. W tym regex, group() zwraca _bbb w Pythonie. Nie potrzeba grup przechwytujących.

Moja rekomendacja jest taka, że ​​jeśli masz możliwość korzystania z grup przechwytywania, aby uzyskać część dopasowania do wyrażenia regularnego, użyj tej metody zamiast obejrzenia.

+3

Jest to o wiele bardziej przydatna odpowiedź niż ta zaakceptowana. – drstevok

0

Użyj metody grup w obiekcie dopasowania zamiast w grupie. Zwraca listę wszystkich buforów przechwytywania. Metoda grupowa bez argumentów zwraca całe dopasowanie wyrażenia regularnego.