101 votes

Comment remplacer uniquement une partie de la correspondance avec python re.sub

Je dois correspondre à deux cas par une expression régulière et effectuer un remplacement

'long.file.name.jpg' -> 'long.file.name_suff.jpg'

'long.file.name_a.jpg' -> 'long.file.name_suff.jpg'

J'essaie de faire ce qui suit

re.sub('(\_a)?\.[^\.]*$' , '_suff.',"long.file.name.jpg")

Mais cela coupe l'extension '.jpg' et j'obtiens

long.file.name_suff. au lieu de long.file.name_suff.jpg Je comprends que c'est à cause de la partie [^.]*$ mais je ne peux pas l'exclure, car je dois trouver la dernière occurrence de '_a' à remplacer ou le dernier '.'

Y a-t-il un moyen de ne remplacer que la partie de la correspondance ?

138voto

Amber Points 159296

Placez un groupe de capture autour de la partie que vous voulez conserver, puis incluez une référence à ce groupe de capture dans votre texte de remplacement.

re.sub(r'(\_a)?\.([^\.]*)$' , r'_suff.\2',"long.file.name.jpg")

52voto

Amarghosh Points 33957
 re.sub(r'(?:_a)?\.([^.]*)$', r'_suff.\1', "long.file.name.jpg")

?: commence un groupe sans correspondance (réponse SO), donc (?:_a) correspond au _a mais ne le compte pas, le point d'interrogation suivant le rend optionnel.

Donc en anglais, cela signifie, correspondre à la fin . qui suit (ou non) le modèle _a

Une autre manière de faire cela serait d'utiliser un lookbehind (voir ici). Je le mentionne car ils sont très utiles, mais je n'en connaissais pas l'existence pendant 15 ans à utiliser les ER

11voto

Gumbo Points 279147

Il suffit de mettre l'expression pour l'extension dans un groupe, de la capturer et de la référencer dans le remplacement :

re.sub(r'(?:_a)?(\.[^\.]*)$' , r'_suff\1',"long.file.name.jpg")

De plus, en utilisant le groupe non capturant (?:…), re n'enregistre pas trop d'informations inutiles.

10voto

Ahmet DAL Points 824

Vous pouvez le faire en excluant les parties à remplacer. Je veux dire, vous pouvez dire au module regex; "faites correspondre ce motif, mais remplacez une partie de celui-ci".

re.sub(r'(?<=long.file.name)(\_a)?(?=\.([^\.]*)$)' , r'_suff',"long.file.name.jpg")
>>> 'long.file.name_suff.jpg'

Les parties long.file.name et .jpg sont utilisées pour la correspondance, mais elles sont exclues du remplacement.

0voto

grantr Points 178

J'ai voulu utiliser des groupes de capture pour remplacer une partie spécifique d'une chaîne de caractères afin de m'aider à l'analyser plus tard. Considérez l'exemple ci-dessous:

s= '  110 SOLANA ROAD, SUITE 102PONTE VEDRA BEACH, FL32082  '

re.sub(r'(

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X