2010-05-04 17 views
34

ho bisogno di abbinare due casi da un'espressione reg e fare la sostituzionecome sostituire solo una parte del match con pitone re.sub

'long.file.name.jpg' -> 'long.file.name_ suff .jpg'

'long.file.name_ un .jpg' -> 'long.file.name_ suff .jpg'

che sto cercando di fare quanto segue

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

Ma questa è tagliato l'estensione '.jpg' e sto ottenendo

long.file.name_suff. invece di long.file.name_suff.jpg Capisco che questo sia dovuto alla parte [^.] * $, ma non posso escluderlo, perché Devo trovare l'ultima occorrenza di '_a' per sostituire o durare ' .'

C'è un modo per sostituire solo una parte della partita?

+0

perché stai sfuggendo alla sottolineatura '(\\ _ a)?' – Amarghosh

risposta

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

?: inizia un gruppo non corrispondente (SO answer), in modo (?:_a) sta abbinando la _a ma non enumerare esso, il seguente punto di domanda lo rende opzionale.

Quindi, in inglese, questo dice, corrisponde al fine .<anything> che segue (o non) il modello _a

Un altro modo per farlo sarebbe quello di utilizzare un lookbehind (see here). Citando questo perché sono super utili, ma non ne ero a conoscenza per 15 anni di attività.

+26

Questa risposta non ha una spiegazione. – PLPeeters

+0

Puoi spiegare per favore ?? –

72

Mettere un gruppo di cattura intorno alla parte che si desidera conservare e quindi includere un riferimento a quel gruppo di cattura all'interno del testo sostitutivo.

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

Grazie per la spiegazione di quello che stai facendo. – GreenMatt

+0

@Amber: dalla tua risposta deduco che a differenza di str.replace(), non possiamo usare le variabili a) in stringhe non elaborate; o b) come argomento per re.sub; o c) entrambi. a) ha senso (credo) ma non sono sicuro di b). Sembra che possiamo usare un nome di variabile per la stringa che sta attraversando l'espressione regolare. Ti piacerebbe chiarire? Grazie. –

7

Basta mettere l'espressione per l'estensione in un gruppo, catturare e fare riferimento alla partita nella sostituzione:

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

Inoltre, utilizzando il gruppo non-cattura (?:…) impedirà re per memorizzare a molte informazioni non necessarie.

+3

È necessario eseguire l'escape del backslash in '\ 1' o inserirlo in' r''' anziché solo '' '. – Amber

1

Puoi farlo escludendo le parti dalla sostituzione. Voglio dire, puoi dire al modulo regex; "combacia con questo modello, ma sostituiscilo con un pezzo".

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

long.file.name e .jpg parti vengono utilizzati sulla corrispondenza, ma sono escludendo da sostituire.

Problemi correlati