Begränsa girighet i reguljära uttryck i Python
Reguljära uttryck är som standard giriga. Det betyder att de fångar maximalt möjligt antal tecken. Låt oss analysera med ett exempel. Antag att vi har följande sträng:
txt = 'aeeex zzz x kkk'
I denna sträng vill vi hitta delsträngen
'aeeex' enligt följande mönster:
bokstaven 'a', sedan valfritt tecken
en eller flera gånger, sedan bokstaven 'x':
res = re.sub('a.+x', '!', txt)
print(res)
Även om vi vill få strängen '! zzz
x kkk', kommer strängen '! kkk' att skrivas ut.
Anledningen är att vårt reguljära uttryck söker
alla tecken från bokstaven 'a' till bokstaven
'x'. Men i vår sträng finns två bokstäver
'x'! På grund av girigheten händer det att
det reguljära uttrycket söker till den sista 'x':en,
varmed det fångar något annat än vad vi
behövde.
Naturligtvis är detta beteende oftast vad vi behöver. Men just i det här fallet måste vi avaktivera girigheten och tala om för det reguljära uttrycket att det ska söka till första 'x':en. I detta fall ska man sätta ett frågetecken efter repetitionsoperatorn:
res = re.sub('a.+?x', '!', txt)
print(res) # skriver ut strängen '! zzz x kkk'
Girighet kan begränsas för alla repetitionsoperatorer:
både *, och ?, och
{} - så här: *?, ??
och {}?.
Given är en sträng:
txt = 'aba accca azzza wwwwa'
Skriv ett reguljärt uttryck som hittar alla
strängar vars kanter är bokstäverna
'a', och ersätter var och en av dem med
'!'. Mellan bokstäverna 'a' kan det
finnas vilket tecken som helst (förutom 'a').