2013-05-23 22 views
209

Ho un file di parametri del moduloPython String.Replace espressione regolare

parameter-name parameter-value 

dove i parametri possono essere in qualsiasi ordine, ma c'è solo un parametro per riga. Voglio sostituire il valore di parametro di un parametro con un nuovo valore.

Sto usando una funzione di sostituzione linea precedentemente registrata (Search and replace a line in a file in Python) per sostituire la linea che utilizza python string.replace (modello, sotto). L'espressione regolare che sto usando funziona ad esempio in vim ma non sembra funzionare in string.replace. Ecco l'espressione regolare che sto usando:

line.replace("^.*interfaceOpDataFile.*$/i", "interfaceOpDataFile %s" % (fileIn)) 

dove interfaceOpDataFile è il nome del parametro che sto sostituendo (/ i per case insensitive) e il nuovo valore del parametro è il contenuto della variabile filein. C'è un modo per far sì che Python riconosca questa espressione regolare oppure esiste un altro modo per eseguire questa operazione? Grazie in anticipo.

risposta

310

str.replace()v2 | v3 non riconosce le espressioni regolari.

Per eseguire una sostituzione utilizzando un'espressione regolare, utilizzare re.sub()v2 | v3.

Ad esempio:

import re 

line = re.sub(
      r"(?i)^.*interfaceOpDataFile.*$", 
      "interfaceOpDataFile %s" % fileIn, 
      line 
     ) 

In un ciclo, sarebbe meglio per compilare l'espressione regolare prima:

import re 

regex = re.compile(r"^.*interfaceOpDataFile.*$", re.IGNORECASE) 
for line in some_file: 
    line = regex.sub("interfaceOpDataFile %s" % fileIn, line) 
    # do something with the updated line 
+19

Utilizzando la compilazione di fuori del ciclo è consiglio grande, bella sfumatura lì - grazie. – pokero

+3

Ho dovuto passare in 'flags = re.MULTILINE' come ultimo argomento a' re.sub' per farlo funzionare, il che ha senso- [leggi qui nei documenti qui] (https: // docs .python.org/2/library/re.html # re.MULTILINE) – tobek

+2

compilazioni regex sono memorizzate nella cache ([docs] (https://docs.python.org/3.6/library/re.html#re.compile)) , quindi la compilazione non è nemmeno necessaria. Ma come si mostra, se si compila, compilare al di fuori del ciclo. – alttag

188

Siete alla ricerca per la funzione re.sub.

import re 
s = "Example String" 
replaced = re.sub('[ES]', 'a', s) 
print replaced 

stamperà axample atring

8

re.sub è sicuramente quello che state cercando. E così sai, non hai bisogno delle ancore e dei caratteri jolly.

re.sub(r"(?i)interfaceOpDataFile", "interfaceOpDataFile %s" % filein, line) 

farà la stessa cosa - corrispondenti la prima stringa che assomiglia a "interfaceOpDataFile" e la sua sostituzione.

+0

ho bisogno di sostituire l'intera linea perché il file originale sarà avere qualcosa di simile: 'interfaceOpDataFile SomeDummyFile.txt' e mi vorrà sostituirlo con: ' interfaceOpDataFile SomeUsefulFile.txt' Se non includo le ancore come farò a sostituire so che voglio sbarazzarmi di 'SomeDummyFile.txt'? –

+0

Ah, ho capito male quello che stavi facendo con la sostituzione. Se ogni coppia è sulla propria linea, non è ancora necessario l'ancoraggio delle ancore. 'Re.sub (r "(? I) (interfaceOpDataFile). *", R '\ 1 UsefulFile', linea)' Ci vorrà tutta la linea, catturare il nome farvi riflettere, e aggiungerlo indietro il la sostituzione per voi. – Nelz11

7

In sintesi

import sys 
import re 

f = sys.argv[1] 
find = sys.argv[2] 
replace = sys.argv[3] 
with open (f, "r") as myfile: 
    s=myfile.read() 
ret = re.sub(find,replace, s) # <<< This is where the magic happens 
print ret