2013-05-23 46 views
209

Ich habe eine Parameterdatei des FormularsPython string.replace regulärer Ausdruck

parameter-name parameter-value 

, wo die Parameter in beliebiger Reihenfolge sein können, aber es ist nur ein Parameter pro Zeile. Ich möchte den Parameterwert eines Parameters durch einen neuen Wert ersetzen.

Ich benutze eine Zeile ersetzen Funktion zuvor (Search and replace a line in a file in Python), um die Zeile, die Python string.replace (Muster, subst) verwendet ersetzt. Der reguläre Ausdruck, den ich verwende, funktioniert zum Beispiel in vim, scheint aber in string.replace nicht zu funktionieren. Hier ist der reguläre Ausdruck, die ich verwende:

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

wo interfaceOpDataFile ist der Parametername, den ich ersetzen (/ i für Groß- und Kleinschreibung) und der neue Parameterwert ist der Inhalt der FileIn variabel. Gibt es eine Möglichkeit Python zu bekommen diesen regulären Ausdruck zu erkennen oder sonst wird es eine andere Möglichkeit, diese Aufgabe zu erfüllen? Danke im Voraus.

Antwort

310

str.replace()v2 | v3 erkennt nicht reguläre Ausdrücke.

Um eine Ersetzung mithilfe eines regulären Ausdrucks durchzuführen, verwenden Sie re.sub()v2 | v3.

Zum Beispiel:

import re 

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

In einer Schleife, wäre es besser, den regulären Ausdruck zu kompilieren zuerst:

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

außerhalb der Schleife gibt es gute Ratschläge, schöne Nuance Mit kompilieren - danke. – pokero

+3

Ich hatte in 'flags = re.MULTILINE' als das letzte Argument' re.sub' um diese, was Sinn macht, zur Arbeit zu kommen passieren - [hier über sie in der Dokumentation lesen] (https: // docs .python.org/2/library/re.html # re.MULTILINE) – tobek

+2

regex Compilations werden zwischengespeichert ([docs] (https://docs.python.org/3.6/library/re.html#re.compile)) , so kompilieren ist nicht einmal notwendig. Aber wenn Sie kompilieren, kompilieren Sie außerhalb der Schleife. – alttag

188

Sie sind für die re.sub Funktion suchen.

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

druckt axample atring

8

re.sub ist auf jeden Fall, was Sie suchen. Und damit Sie wissen, brauchen Sie die Anker und die Wildcards nicht.

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

wird das gleiche tun - die erste Teilkette passend, die wie „interfaceOpDataFile“ sieht und ihn zu ersetzen.

+0

Ich brauche die gesamte Zeile zu ersetzen, weil die ursprüngliche Datei so etwas wie haben: 'interfaceOpDataFile SomeDummyFile.txt' und ich werde es ersetzen wollen: ' interfaceOpDataFile SomeUsefulFile.txt' Wenn ich die Anker nicht einschließe, wie werde ich wissen, dass ich 'SomeDummyFile.txt' loswerden will? –

+0

Ah, ich habe genau verstanden, was du mit dem Ersatz gemacht hast. Wenn jedes Paar auf einer eigenen Linie ist, brauchen Sie die Anker nicht explizit. 're (r) (? i) (interfaceOpDataFile). *", r '\ 1 UsefulFile', Zeile) "Dies nimmt die ganze Zeile, erfassen Sie den Argumentnamen und fügen Sie es als Ersatz für Sie zurück. – Nelz11

7

Als Zusammenfassung

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