Positiv og negativ lookahead i Python regex
Noen ganger må man løse en oppgave av denne typen:
finn strengen 'aaa' og erstatt den
med '!', men bare hvis etter
'aaa' kommer 'x', mens
'x' i seg selv ikke skal erstattes. Hvis vi
prøver å løse oppgaven 'rett frem',
vil det ikke lykkes:
txt = 'aaax baaa'
res = re.sub('aaax', '!', txt)
print(res) # vil skrive '! baaa', men ønsket var '!x baaa'
Lookahead
For å løse oppgaven trengs en måte å si at
'x' ikke skal erstattes. Dette gjøres
ved hjelp av spesielle parenteser (?= ),
som bare ser, men ikke tar med seg.
Disse parentesene kalles positiv lookahead.
Positiv - fordi 'x'
(i vårt tilfelle) må være til stede - bare da
vil erstatningen skje.
La oss bruke disse parentesene for å løse vår oppgave:
txt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # vil skrive '!x aaab
Det finnes også negativ lookahead
- (?! ) - den sier, tvert imot,
at noe ikke skal være til stede. I det følgende
eksempelet vil erstatning skje, bare hvis
det etter 'aaa' IKKE kommer 'x':
txt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)
print(res) # vil skrive 'aaax !b'
Lookbehind
På samme måte finnes det positiv
lookbehind - (?<= ). I
følgende eksempel vil erstatning skje, bare
hvis det foran 'aaa' står 'x':
txt = 'xaaa'
res = re.sub('(?<=x)aaa', '!', txt)
print(res) # vil skrive 'x!'
Og det finnes også negativ lookbehind
- (?<! ). I følgende eksempel
vil erstatning skje, bare hvis det foran
'aaa' ikke står 'x':
txt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)
print(res) # vil skrive 'b!'
Praktiske oppgaver
Gitt en streng som inneholder funksjonsnavn:
txt = 'func1() func2() func3()'
Få en liste med funksjonsnavn fra strengen.
Gitt en streng med en tag:
txt = '<a href="" class="eee" id="zzz">'
Få en liste med navn på attributtene til denne taggen.
Gitt en streng med variabler:
txt = '$aaa $bbb $ccc xxxx'
Få delstrengene som kommer etter dollartegnet.