2009-05-28 20 views

risposta

148

Il tipo string non supporta questo. Probabilmente stai meglio usando the regular expression sub method con l'opzione re.IGNORECASE.

>>> import re 
>>> insensitive_hippo = re.compile(re.escape('hippo'), re.IGNORECASE) 
>>> insensitive_hippo.sub('giraffe', 'I want a hIPpo for my birthday') 
'I want a giraffe for my birthday' 
+7

Se si esegue solo una sostituzione singola o si desidera salvare righe di codice, è più efficiente utilizzare una singola sostituzione con re.sub e il flag (? I): re.sub ('(? I) '+ re.escape ('hippo'), 'giraffe', 'Voglio un hIPpo per il mio compleanno') –

+8

+1 per re.escape – daboross

+2

Perché ** re.escape ** solo per una stringa di lettere? Grazie. – Elena

61
import re 
pattern = re.compile("hello", re.IGNORECASE) 
pattern.sub("bye", "hello HeLLo HELLO") 
# 'bye bye bye' 
2

Questo non richiede regualerexp

def ireplace(old, new, text): 
    """ 
    Replace case insensitive 
    Raises ValueError if string not found 
    """ 
    index_l = text.lower().index(old.lower()) 
    return text[:index_l] + new + text[index_l + len(old):] 
+2

Buono, tuttavia ciò non modifica tutte le occorrenze del vecchio con nuovo, ma solo la prima occorrenza. – rsmoorthy

+3

È meno leggibile rispetto alla versione regex. Non c'è bisogno di reinventare la ruota qui. –

+0

Sarebbe interessante fare un confronto delle prestazioni tra questa e le versioni con upvoted, potrebbe essere più veloce, che è importante per alcune applicazioni. O potrebbe essere più lento perché fa più lavoro nell'interpretazione di Python. –

5

Proseguendo sulla risposta di bFloch, questa funzione cambierà non una, ma tutte le occorrenze di vecchio e il nuovo - in modo insensibile caso.

def ireplace(old, new, text): 
    idx = 0 
    while idx < len(text): 
     index_l = text.lower().find(old.lower(), idx) 
     if index_l == -1: 
      return text 
     text = text[:index_l] + new + text[index_l + len(old):] 
     idx = index_l + len(new) 
    return text 
+0

Molto ben fatto. Molto meglio di regex; gestisce tutti i tipi di caratteri, mentre la regex è molto pignola su tutto ciò che non è alfanumerico. Risposta preferita IMHO. – fyngyrz

+0

Tutto quello che devi fare è sfuggire alla regex: la risposta accettata è molto più breve e più facile da leggere di questa. –

-1

mai inviato una risposta prima e questa discussione è molto vecchio, ma mi si avvicinò con un altro sollution e capito che potevo mettere le respons, Im non stagionato in programmazione Python, quindi se ci sono svantaggi appearant ad esso, si prega di puntare fuori dalla sua un buon apprendimento :)

i='I want a hIPpo for my birthday' 
key='hippo' 
swp='giraffe' 

o=(i.lower().split(key)) 
c=0 
p=0 
for w in o: 
    o[c]=i[p:p+len(w)] 
    p=p+len(key+w) 
    c+=1 
print(swp.join(o)) 
+2

Per l'apprendimento: generalmente quando si effettua una ricerca e si sostituisce una stringa, è meglio non dover prima trasformarla in un array. Ecco perché la prima risposta è probabilmente la migliore. Mentre sta usando un modulo esterno, considera la stringa come un'intera stringa. È anche un po 'più chiaro cosa sta succedendo nel processo. – isaaclw

25

Molto semplice, in una sola riga:

import re 
re.sub("(?i)hello","bye", "hello HeLLo HELLO") #'bye bye bye' 
re.sub("(?i)he\.llo","bye", "he.llo He.LLo HE.LLO") #'bye bye bye' 

Oppure, utilizzare le "bandiere" opzionali argomento:

import re 
re.sub("hello", "bye", "hello HeLLo HELLO", flags=re.I) #'bye bye bye' 
re.sub("he\.llo", "bye", "he.llo He.LLo HE.LLO", flags=re.I) #'bye bye bye' 
1

Come Blair Conrad dice che string.replace non supporta questo.

Utilizzare la regex re.sub, ma ricordarsi di sfuggire prima alla stringa di sostituzione. Nota che non ci sono flag-option in 2.6 per re.sub, quindi dovrai usare il modificatore incorporato '(?i)' (o un oggetto RE, vedi la risposta di Blair Conrad). Inoltre, un altro trabocchetto è che sub processerà le escape backslash nel testo sostitutivo, se viene fornita una stringa. Per evitare questo si può invece passare in una lambda.

Ecco una funzione:

import re 
def ireplace(old, repl, text): 
    return re.sub('(?i)'+re.escape(old), lambda m: repl, text) 

>>> ireplace('hippo?', 'giraffe!?', 'You want a hiPPO?') 
'You want a giraffe!?' 
>>> ireplace(r'[binfolder]', r'C:\Temp\bin', r'[BinFolder]\test.exe') 
'C:\\Temp\\bin\\test.exe' 
0

stavo avendo \ t di essere convertito al escape sequences (scorrere un po 'verso il basso), quindi ho notato che re.sub convertiti backslash fuggiti caratteri da sequenze di escape.

Per evitare che ho scritto il seguente:

case insensitive Sostituire.

import re 
    def ireplace(findtxt, replacetxt, data): 
     return replacetxt.join( re.compile(findtxt, flags=re.I).split(data) ) 

Inoltre, se si desidera sostituire con i caratteri di escape, come le altre risposte qui che stanno ottenendo i caratteri speciali bashslash significato convertiti in sequenze di escape, basta decodificare il trovare e, o sostituire stringa. In Python 3, potrebbe avere a che fare qualcosa di simile .decode ("unicode_escape") # python3

findtxt = findtxt.decode('string_escape') # python2 
replacetxt = replacetxt.decode('string_escape') # python2 
data = ireplace(findtxt, replacetxt, data) 

testato in Python 2.7.8

Speranza che aiuta.