Lookahead și Lookbehind pozitiv și negativ în expresiile regulate Python
Uneori trebuie să rezolvi o problemă de acest tip:
găsește șirul 'aaa' și înlocuiește-l
cu '!', dar numai dacă după
'aaa' se află 'x', iar
'x' în sine să nu fie înlocuit. Dacă
încercăm să rezolvăm problema 'direct',
nu vom reuși:
txt = 'aaax baaa'
res = re.sub('aaax', '!', txt)
print(res) # va afișa '! baaa', dar am vrut '!x baaa'
Lookahead
Pentru a rezolva problema, este nevoie de o modalitate de a spune
că 'x' nu trebuie înlocuit. Acest lucru se face
cu ajutorul unor paranteze speciale (?= ),
care doar se uită, dar nu preiau
cu ele.
Aceste paranteze se numesc lookahead pozitiv. Pozitiv - deoarece 'x'
(în cazul nostru) trebuie să fie prezent - doar atunci
va avea loc înlocuirea.
Să aplicăm aceste paranteze pentru a rezolva problema noastră:
txt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # va afișa '!x aaab
Există și lookahead negativ
- (?! ) - el, dimpotrivă, spune
că ceva nu trebuie să fie. În următorul
exemplu, înlocuirea va avea loc doar dacă
după 'aaa' se află NU 'x':
txt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)
print(res) # va afișa 'aaax !b'
Lookbehind
În mod analog, există lookbehind pozitiv
- (?<= ). În
următorul exemplu, înlocuirea va avea loc doar
dacă înaintea 'aaa' se află 'x':
txt = 'xaaa'
res = re.sub('(?<=x)aaa', '!', txt)
print(res) # va afișa 'x!'
Și există și lookbehind negativ
- (?<! ). În următorul exemplu
înlocuirea va avea loc doar dacă înaintea
'aaa' nu se află 'x':
txt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)
print(res) # va afișa 'b!'
Probleme practice
Este dat un șir care conține nume de funcții:
txt = 'func1() func2() func3()'
Obțineți un array cu numele funcțiilor din șir.
Este dat un șir cu un tag:
txt = '<a href="" class="eee" id="zzz">'
Obțineți un array cu numele atributelor acestui tag.
Este dat un șir cu variabile:
txt = '$aaa $bbb $ccc xxxx'
Obțineți subșirurile dinaintea cărora se află simbolul dolar.