Lookahead et lookbehind positifs et négatifs dans les regex Python

Parfois, il faut résoudre un problème de ce type : trouver la chaîne 'aaa' et la remplacer par '!', mais seulement si après 'aaa' se trouve 'x', et ne pas remplacer 'x' lui-même. Si nous essayons de résoudre le problème 'directement', nous n'y arriverons pas :

pythontxt = 'aaax baaa'
res = re.sub('aaax', '!', txt)

print(res) # affichera '! baaa', alors que nous voulions '!x baaa'

Lookahead

Pour résoudre le problème, il faut un moyen de dire que 'x' ne doit pas être remplacé. Cela se fait à l'aide de parenthèses spéciales (?= ), qui vérifient simplement sans consommer les caractères.

Ces parenthèses sont appelées lookahead positif. Positif - car 'x' (dans notre cas) doit être présent - alors seulement le remplacement aura lieu.

Utilisons ces parenthèses pour résoudre notre problème :

pythontxt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # affichera '!x aaab

Il existe aussi le lookahead négatif - (?! ) - il dit, au contraire, que quelque chose ne doit pas être présent. Dans l'exemple suivant, le remplacement aura lieu seulement si après 'aaa' il n'y a PAS 'x' :

pythontxt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)

print(res) # affichera 'aaax !b'

Lookbehind

De manière analogue, il existe le lookbehind positif - (?<= ). Dans l'exemple suivant, le remplacement aura lieu seulement si avant 'aaa' se trouve 'x' :

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

print(res) # affichera 'x!'

Et il existe aussi le lookbehind négatif - (?<! ). Dans l'exemple suivant le remplacement aura lieu, seulement si avant 'aaa' ne se trouve pas 'x' :

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

print(res) # affichera 'b!'

Problèmes pratiques

Задание 1

Soit une chaîne contenant des noms de fonctions :

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

Obtenez un tableau des noms de fonctions à partir de la chaîne.

Задание 2

Soit une chaîne avec une balise :

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

Obtenez un tableau des noms des attributs de cette balise.

Задание 3

Soit une chaîne avec des variables :

pythontxt = '$aaa $bbb $ccc xxxx'

Obtenez les sous-chaînes précédées du symbole dollar.