Negative Lookbehind expression régulière

Le problème exposé dans ce sujet a été résolu.

Salut les agrumes ! :pirate:

J’essaie de faire un remplacement dans une chaîne de caractère pour les espaces insécables en prenant en compte les remplacement HTML &, etc… Pour ça j’ai essayé cette solution :

import re

regexp = re.compile(r'(?<!&\w+);')
text = '&amp;;'
text = regexp.sub('\u202F;', text)

print('"' + text + '"')

Le problème est que le negative lookbehind (le (?<!...)) ne fonctionne qu’avec un regex de longueur défini. J’ai beau réfléchir à un workaround mais je ne trouve rien qui soit élégant comme façon de faire.

Zestement, :zorro:

Salut,

En consommant les caractères puis en testant ta capture dans une fonction ça peut le faire :

import re

regexp = re.compile(r'(&\w+)?;')
text = 'w&scw;d;;&amp;;'
text = regexp.sub(lambda m: '\u202F;' if m.group(1) is None else m.group(1) + ';', text)

print('"' + text + '"')
// "w&scw;d ; ;&amp; ;"

@Heziode Je pensais à un quelque chose de simple comme e&amp;;;.

@Chinoisfurax, j’ai réfléchi à ta solution et du coup ça donnerait :

  • on cherche si il y a 0 ou + occurences d’un caractère HTML &...; avec un ; après
  • Dans la lambda (d’ailleurs ça serait pas return\u202F;if ... car sinon le \u202F; ne sera pas communiqué à regex.sub ou c’est implicite ?), si il n’y a pas de &... (if m.group(1) is None), alors c’est qu’on a affaire à un point point-virgule sans caractère HTML. Sinon c’est que c’est un caractère HTML et donc on le remet en place (else m.group(1) + ';')

C’est bien ça que c’est censé faire. Si c’est ça alors je pense que tu as trouvé une solution ! J’essaierai dès que j’ai accès à python et j’éditerai.

  • on cherche si il y a 0 ou + occurences d’un caractère HTML &...; avec un ; après
Vanadiae

Oui, plus exactement on cherche tous les points-virgules plus les éventuels caractères précédents correspondant à des entités html pour les détecter et les exclure ensuite. En vrai il faudrait rajouter les codes de type &#\d+; pour prendre tous les cas d’entités, et exclure l’entité qui correspond à ton espace insécable à moins de la remplacer avant : re.compile(r'(&(?i:[a-z\d]+|#\d+))?(?<!&(nbsp|#160););'). Après, si ça devient plus complexe, avec des balises par exemple, il sera peut-être plus judicieux d’utiliser un parseur carrément.

  • Dans la lambda (d’ailleurs ça serait pas return\u202F;if ... car sinon le \u202F; ne sera pas communiqué à regex.sub ou c’est implicite ?), si il n’y a pas de &... (if m.group(1) is None), alors c’est qu’on a affaire à un point point-virgule sans caractère HTML. Sinon c’est que c’est un caractère HTML et donc on le remet en place (else m.group(1) + ';')
Vanadiae

La lambda renvoie la valeur directement, tu as saisi l’idée.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte