2012-09-26 11 views
32

Ho una stringa in Python, dicono The quick @red fox jumps over the @lame brown dog.pitone sostituire schema corde con uscita della funzione

sto cercando di sostituire ciascuna delle parole che iniziano con @ con l'uscita di una funzione che prende la parola come discussione.

def my_replace(match): 
    return match + str(match.index('e')) 

#Psuedo-code 

string = "The quick @red fox jumps over the @lame brown dog." 
string.replace('@%match', my_replace(match)) 

# Result 
"The quick @red2 fox jumps over the @lame4 brown dog." 

C'è un modo intelligente per farlo?

+1

quello che hai è buono. lo fai in una dichiarazione. – tuxuday

risposta

58

È possibile passare una funzione a re.sub. La funzione riceverà un oggetto di corrispondenza come argomento, utilizzare .group() per estrarre la corrispondenza come stringa.

>>> def my_replace(match): 
...  match = match.group() 
...  return match + str(match.index('e')) 
... 
>>> re.sub(r'@\w+', my_replace, string) 
'The quick @red2 fox jumps over the @lame4 brown dog.' 
+1

Bello. Non sapevo di poter passare una funzione a re.sub, ma sentivo che dovrei essere in grado di farlo. – nathancahill

1

Prova:

import re 

match = re.compile(r"@\w+") 
items = re.findall(string) 
for item in items: 
    string = string.replace(item, my_replace(item) 

questo vi permetterà di sostituire tutto ciò che inizia con @ con qualunque l'uscita della funzione è. Non ero molto chiaro se hai bisogno di aiuto anche con la funzione. Fatemi sapere se questo è il caso

+0

're.findall (motivo, stringa)' - Correggere –

+0

Questo è in realtà piuttosto utile in quanto consente di sostituire solo gli elementi corrispondenti nella stringa. – Dannid

0

Un corto con espressioni regolari e ridurre:

>>> import re 
>>> pat = r'@\w+' 
>>> reduce(lambda s, m: s.replace(m, m + str(m.index('e'))), re.findall(pat, string), string) 
'The quick @red2 fox jumps over the @lame4 brown dog.' 
4

non ero a conoscenza si poteva passare una funzione a una re.sub() sia. Riffing sulla risposta di @Janne Karila per risolvere un problema che ho avuto, l'approccio funziona anche per più gruppi di cattura.

import re 

def my_replace(match): 
    match1 = match.group(1) 
    match2 = match.group(2) 
    match2 = match2.replace('@', '') 
    return u"{0:0.{1}f}".format(float(match1), int(match2)) 

string = 'The first number is [email protected], and the second number is [email protected]' 
result = re.sub(r'([0-9]+.[0-9]+)(@[0-9]+)', my_replace, string) 

print(result) 

uscita:

The first number is 14.2, and the second number is 50.6000.

Questo semplice esempio richiede tutte le cattura essere presenti (gruppi opzionali).

Problemi correlati