Ograniczanie zachłanności w wyrażeniach regularnych w Pythonie
Wyrażenia regularne domyślnie są zachłanne. Oznacza to, że przechwytują maksymalną możliwą liczbę znaków. Przeanalizujmy to na przykładzie. Załóżmy, że mamy taki ciąg znaków:
txt = 'aeeex zzz x kkk'
W tym ciągu chcemy znaleźć podciąg
'aeeex' według następującego wzorca:
litera 'a', następnie dowolny znak
jeden lub więcej razy, następnie litera 'x':
res = re.sub('a.+x', '!', txt)
print(res)
Chociaż oczekujemy otrzymania ciągu '! zzz
x kkk', wypisany zostanie ciąg '! kkk'.
Chodzi o to, że nasze wyrażenie regularne szuka
wszystkich znaków od litery 'a' do litery
'x'. Ale w naszym ciągu są dwie litery
'x'! Z powodu zachłanności okazuje się, że
wyrażenie regularne szuka do ostatniego 'x',
tym samym przechwytując nie to, czego
potrzebowaliśmy.
Oczywiście często takie zachowanie jest właśnie tym, czego potrzebujemy. Ale konkretnie w tym przypadku należy wyłączyć zachłanność i nakazać wyrażeniu regularnemu, żeby szukało do pierwszego 'x'. W tym przypadku należy po operatorze powtórzenia postawić znak zapytania:
res = re.sub('a.+?x', '!', txt)
print(res) # wypisze ciąg '! zzz x kkk'
Zachłanność można ograniczać wszystkim operatorom
powtórzenia: i *, i ?, i
{} - o tak: *?, ??
i {}?.
Dany jest ciąg:
txt = 'aba accca azzza wwwwa'
Napisz wyrażenie regularne, które znajdzie wszystkie
ciągi, na których brzegach znajdują się litery
'a', i zastąpi każdy z nich
'!'. Między literami 'a' może
znajdować się dowolny znak (oprócz 'a').