web-dev-qa-db-fra.com

Comment remplacer seulement une partie de la correspondance par python re.sub

Je dois faire correspondre deux cas par une expression de reg et faire 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 c'est coupé l'extension ".jpg" et je reçois

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

Existe-t-il un moyen de remplacer seulement une partie du match?

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

?: démarre un groupe qui ne correspond pas ( réponse SO ), donc (?:_a) correspond à _a mais sans l'énumérer, le point d'interrogation suivant le rend facultatif.

Donc en anglais, cela dit, correspond à la fin .<anything> qui suit (ou non) le motif _a

Une autre façon de le faire serait d'utiliser un lookbehind ( voir ici ). Mentionner cela parce qu'ils sont super utiles, mais je ne les connaissais pas depuis 15 ans à faire des RE

24
Amarghosh

Placez un groupe de capture autour de la partie que vous souhaitez 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")
91
Amber

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

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

En outre, en utilisant le groupe non capturant (?:…) empêchera de réenregistrer de nombreuses informations inutiles.

9
Gumbo

Vous pouvez le faire en excluant le remplacement des pièces. Je veux dire, vous pouvez dire au module regex; msgstr "correspond à ce motif, mais remplacez - en un morceau".

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

long.file.name et . jpg les pièces sont utilisées pour l'appariement, mais elles sont exclues du remplacement.

6
Ahmet DAL