Ahneuden rajoittaminen säännöllisissä lausekkeissa Pythonissa
Säännölliset lausekkeet ovat oletusarvoisesti ahneita. Tämä tarkoittaa, että ne sieppaavat mahdollisimman suuren määrän merkkejä. Käydään se läpi esimerkin avulla. Oletetaan, että meillä on seuraava merkkijono:
txt = 'aeeex zzz x kkk'
Tästä merkkijonosta haluamme löytää osamerkkijonon
'aeeex' seuraavan mallin mukaisesti:
kirjain 'a', sitten mikä tahansa merkki
yksi tai useampi kerta, sitten kirjain 'x':
res = re.sub('a.+x', '!', txt)
print(res)
Vaikka meidän pitäisi saada merkkijono '! zzz
x kkk', tulostuu merkkijono '! kkk'.
Syynä on, että säännöllisemme etsii
kaikki merkit kirjaimesta 'a' kirjaimeen
'x' asti. Mutta merkkijonossamme on kaksi kirjainta
'x'! Ahneuden vuoksi käy niin, että
säännöllinen lauseke etsii viimeiseen x-kirjaimeen asti,
ja sieppaa näin ollen muuta kuin mitä tarvitsimme.
Tietenkin usein tämä käyttäytyminen on juuri se mitä tarvitsemme. Mutta nyt tässä tapauksessa ahneus on kumottava ja säännölliselle lausekkeelle on kerrottava, että sen tulee etsiä ensimmäiseen x-kirjaimeen asti. Tässä tapauksessa toistooperaattorin jälkeen tulee laittaa kysymysmerkki:
res = re.sub('a.+?x', '!', txt)
print(res) # tulostaa merkkijonon '! zzz x kkk'
Ahneutta voidaan rajoittaa kaikille toistooperaattoreille:
sekä *, että ?, ja
{} - näin: *?, ??
ja {}?.
Annettu merkkijono:
txt = 'aba accca azzza wwwwa'
Kirjoita säännöllinen lauseke, joka löytää kaikki
merkkijonot, joiden reunoilla on kirjaimet
'a', ja korvaa jokainen niistä
'!':llä. Kirjainten 'a' välissä voi
olla mikä tahansa merkki (paitsi 'a').