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:

pythontxt = '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:

pythontxt = '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':

pythontxt = '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':

pythontxt = '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':

pythontxt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)

print(res) # vil skrive 'b!'

Praktiske oppgaver

Задание 1

Gitt en streng som inneholder funksjonsnavn:

pythontxt = 'func1() func2() func3()'

Få en liste med funksjonsnavn fra strengen.

Задание 2

Gitt en streng med en tag:

pythontxt = '<a href="" class="eee" id="zzz">'

Få en liste med navn på attributtene til denne taggen.

Задание 3

Gitt en streng med variabler:

pythontxt = '$aaa $bbb $ccc xxxx'

Få delstrengene som kommer etter dollartegnet.