Positiv och negativ lookahead och lookbehind i Python regex
Ibland måste man lösa en uppgift av detta slag:
hitta strängen 'aaa' och ersätt den
med '!', men endast om efter
'aaa' kommer 'x', medan
'x' i sig inte ska ersättas. Om vi
försöker lösa uppgiften 'rakt på',
kommer det inte att lyckas:
txt = 'aaax baaa'
res = re.sub('aaax', '!', txt)
print(res) # skriver '! baaa', men vi ville ha '!x baaa'
Lookahead
För att lösa uppgiften behövs ett sätt att säga,
att 'x' inte ska ersättas. Detta görs
med hjälp av speciella parenteser (?= ),
vilka bara tittar, men inte tar med sig.
Dessa parenteser kallas positiv lookahead.
Positiv - eftersom 'x'
(i vårt fall) måste finnas - endast då
kommer ersättningen att ske.
Låt oss använda dessa parenteser för att lösa vår uppgift:
txt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # skriver '!x aaab
Det finns också negativ lookahead
- (?! ) - den säger, tvärtom,
att något inte får finnas. I följande
exempel kommer ersättning att ske, endast om
efter 'aaa' inte kommer 'x':
txt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)
print(res) # skriver 'aaax !b'
Lookbehind
På samma sätt finns positiv
lookbehind - (?<= ). I
följande exempel kommer ersättning att ske, endast
om före 'aaa' kommer 'x':
txt = 'xaaa'
res = re.sub('(?<=x)aaa', '!', txt)
print(res) # skriver 'x!'
Och det finns också negativ lookbehind
- (?<! ). I följande exempel
kommer ersättning att ske, endast om före
'aaa' inte kommer 'x':
txt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)
print(res) # skriver 'b!'
Praktiska uppgifter
Given en sträng som innehåller funktionsnamn:
txt = 'func1() func2() func3()'
Få en array med funktionsnamn från strängen.
Given en sträng med en tagg:
txt = '<a href="" class="eee" id="zzz">'
Få en array med namnen på taggens attribut.
Given en sträng med variabler:
txt = '$aaa $bbb $ccc xxxx'
Få delsträngarna som föregås av dollartecknet.