Lookahead e Lookbehind Positivo e Negativo nelle Espressioni Regolari di Python
A volte è necessario risolvere un problema di questo tipo:
trovare la stringa 'aaa' e sostituirla
con '!', ma solo se dopo
'aaa' c'è 'x', mentre
'x' stesso non deve essere sostituito. Se
proviamo a risolvere il problema 'di forza bruta',
non avremo successo:
txt = 'aaax baaa'
res = re.sub('aaax', '!', txt)
print(res) # restituirà '! baaa', ma volevamo '!x baaa'
Lookahead
Per risolvere il problema, serve un modo per dire
che 'x' non deve essere sostituito. Questo
si fa utilizzando parentesi speciali (?= ),
che semplicemente "guardano", ma non consumano i caratteri.
Queste parentesi sono chiamate lookahead positivo. Positivo - perché 'x'
(nel nostro caso) deve essere presente - solo allora
avverrà la sostituzione.
Applichiamo queste parentesi per risolvere il nostro problema:
txt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # restituirà '!x baaa'
Esiste anche il lookahead negativo
- (?! ) - che, al contrario, dice
che qualcosa non deve essere presente. Nel prossimo
esempio, la sostituzione avverrà solo se
dopo 'aaa' NON c'è 'x':
txt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)
print(res) # restituirà 'aaax !b'
Lookbehind
Analogamente, esiste il lookbehind positivo - (?<= ). Nel
prossimo esempio la sostituzione avverrà solo
se prima di 'aaa' c'è 'x':
txt = 'xaaa'
res = re.sub('(?<=x)aaa', '!', txt)
print(res) # restituirà 'x!'
Ed esiste anche il lookbehind negativo
- (?<! ). Nel prossimo esempio
la sostituzione avverrà solo se prima di
'aaa' NON c'è 'x':
txt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)
print(res) # restituirà 'b!'
Problemi Pratici
Data una stringa contenente nomi di funzioni:
txt = 'func1() func2() func3()'
Ottieni un array dei nomi delle funzioni dalla stringa.
Data una stringa con un tag:
txt = '<a href="" class="eee" id="zzz">'
Ottieni un array dei nomi degli attributi di questo tag.
Data una stringa con variabili:
txt = '$aaa $bbb $ccc xxxx'
Ottieni le sottostringhe che sono precedute dal simbolo del dollaro.