Omezení chamtivosti v regulárních výrazech v Pythonu
Regulární výrazy jsou ve výchozím nastavení chamtivé. To znamená, že zachycují maximální možný počet znaků. Pojďme si to rozebrat na příkladu. Předpokládejme, že máme takovýto řetězec:
txt = 'aeeex zzz x kkk'
V tomto řetězci chceme najít podřetězec
'aeeex' podle následujícího vzoru:
písmeno 'a', poté libovolný znak
jedenkrát nebo vícekrát, poté písmeno 'x':
res = re.sub('a.+x', '!', txt)
print(res)
Ačkoli chceme získat řetězec '! zzz
x kkk', vypíše se řetězec '! kkk'.
Celé je to o tom, že náš regulární výraz hledá
všechny znaky od písmene 'a' až po písmeno
'x'. Ale v našem řetězci jsou dvě písmena
'x'! Kvůli chamtivosti se stane, že
regulární výraz hledá až do toho úplně posledního 'x',
čímž zachytí něco, co jsme nepotřebovali.
Samozřejmě, často je toto chování přesně to, co potřebujeme. Ale konkrétně v tomto případě je třeba zrušit chamtivost a říci regulárnímu výrazu, ať hledá pouze do prvního 'x'. V tomto případě bychom měli za operátor opakování umístit otazník:
res = re.sub('a.+?x', '!', txt)
print(res) # vypíše řetězec '! zzz x kkk'
Chamtivost lze omezit u všech operátorů
opakování: ať už *, ?, nebo
{} - takto: *?, ??
a {}?.
Je dán řetězec:
txt = 'aba accca azzza wwwwa'
Napište regulární výraz, který najde všechny
řetězce, na jejichž okrajích jsou písmena
'a', a nahradí každý z nich
'!'. Mezi písmeny 'a' může
být libovolný znak (kromě 'a').