2015-10-13 22 views
6

Voglio sostituire trattini che appaiono tra lettere con uno spazio usando regex. Ad esempio per sostituire ab-cd con ab cdCome sostituire il trattino tra i caratteri con lo spazio usando regex

Il seguente corrisponde alla sequenza di caratteri, tuttavia sostituisce anche i caratteri [vale a dire. ab-cd risultati in a d, piuttosto che ab cd come io desidero]

new_term = re.sub(r"[A-z]\-[A-z]", " ", original_term) 

Come mi adatto quanto sopra per sostituire solo la parte -?

+0

Ca n fai questo semplicemente sostituendo '-' con uno spazio nella stringa data? Sta usando regex necessario? –

+1

@JeffBridgman sì - voglio solo sostituire quando il trattino si verifica tra i caratteri, e non quando tra lo spazio. per sostituire 'ab-cd', ma non per cambiare' ab - cd' - ['replace' non ha quel controllo]. – kyrenia

risposta

6

è necessario per catturare i personaggi prima e dopo il - ad un gruppo e li usa per la sostituzione, vale a dire:

import re 
subject = "ab-cd" 
subject = re.sub(r"([a-z])\-([a-z])", r"\1 \2", subject , 0, re.IGNORECASE) 
print subject 
#ab cd 

DEMO

http://ideone.com/LAYQWT


REGEX SPIEGAZIONE

([A-z])\-([A-z]) 

Match the regex below and capture its match into backreference number 1 «([A-z])» 
    Match a single character in the range between “A” and “z” «[A-z]» 
Match the character “-” literally «\-» 
Match the regex below and capture its match into backreference number 2 «([A-z])» 
    Match a single character in the range between “A” and “z” «[A-z]» 

\1 \2 

Insert the text that was last matched by capturing group number 1 «\1» 
Insert the character “ ” literally « » 
Insert the text that was last matched by capturing group number 2 «\2» 
6

Utilizzare i riferimenti a gruppi di cattura:

>>> original_term = 'ab-cd' 
>>> re.sub(r"([A-z])\-([A-z])", r"\1 \2", original_term) 
'ab cd' 

Ciò presuppone, naturalmente, che non si può semplicemente fare original_term.replace('-', ' ') per qualsiasi motivo. Forse il tuo testo usa i trattini dove dovrebbe usare trattini o qualcosa del genere.

+0

Non si dovrebbe usare '[A-z]' poiché gli intervalli di espressioni regolari utilizzano l'indice della tabella ascii. Per questo intervallo specifico abbinerai 'A-Z [\]^_ \' a-z'. Tuttavia, puoi usare '(? I)' se vuoi usare 'a-z' come insensibile alla chiave. Ad esempio, puoi avere '(? I) ([a-z]) \ - ([a-z])'. Ad ogni modo, so che la regex originale di OP è che ... ma sto solo dicendo. –

1

è necessario utilizzare look-around:

new_term = re.sub(r"(?i)(?<=[A-Z])-(?=[A-Z])", " ", original_term) 

o catturare gruppi:

new_term = re.sub(r"(?i)([A-Z])-([A-Z])", r"\1 \2", original_term) 

Vedi IDEONE demo

noti che [A-z] corrisponde anche alcuni non-lettere (cioè [, \ , ], ^, _ e `), quindi, suggerisco di sostituirlo con [A-Z] e utilizzare un modificatore senza distinzione tra maiuscole e minuscole (?i).

Si noti che non è necessario sfuggire a un trattino fuori da una classe di caratteri.

2

re.sub() sostituisce sempre l'intera sequenza con la sostituzione.

Una soluzione a sostituire solo il cruscotto sono lookahead e lookbehind asserzioni. Non contano per la sequenza abbinata.

new_term = re.sub(r"(?<=[A-z])\-(?=[A-z])", " ", original_term) 

La sintassi è spiegata nello Python documentation for the re module.

Problemi correlati