2016-06-20 4 views
0

ich den folgenden Code haben, die ich denke, sollte funktionieren, aber scheint nicht zu:Python Suche nach Zeichenfolge in Zeile

old_name = 'Some User' 
new_name = 'New User' 

with open(complete_filename, 'r') as provisioning_file: 
    lines = provisioning_file.read() 
    # if the old_name is in this file 
    if old_name in lines: 
    file_found = 1 
    with open(complete_filename + '.new', 'w') as new_provisioning_file: 
     for line in lines: 
     line = line.replace(old_name, new_name) 
     new_provisioning_file.write(line) 
     # provisioning_file.write(re.sub(old_name, new_name, line)) 

Die Datei complete_filename wird eine Vielzahl von Konfigurationsdateien sein, ich habe Tests gewesen mit einer Auswahl von XML-Dateien, ein Beispiel Ausschnitt aus einem von diesen unten:

<reg reg.1.address="1234" reg.1.label="Some User" > 
     <reg.1.auth reg.1.auth.password="XXXXXXXXXX" reg.1.auth.userId="1234" /> 
     <reg.1.outboundProxy reg.1.outboundProxy.address="sip.example.com" /> 
     <reg.1.server reg.1.server.1.address="sip.example.com" reg.1.server.1.expires="300" reg.1.server.2.expires="300" /> 
     <reg.1.serverFeatureControl reg.1.serverFeatureControl.dnd="0" /> 
    </reg> 

der Code den old_name String und geht in die if Anweisung findet, öffnet dann complete_filename.new zum Schreiben, aber es findet anscheinend nie die alten Name in der Zeilen und gibt nur die Datei wie sie ist (d. h. Es ersetzt nicht new_name für old_name).

Wie aus dem Code ersichtlich ist, habe ich auch mit re mit ähnlichen Ergebnissen experimentiert. Was vermisse ich?

Antwort

3
lines = provisioning_file.read() 

Das sieht nicht richtig für mich. read() gibt keine Liste von Zeilen zurück, sondern gibt eine einzelne Zeichenfolge zurück. Wenn Sie also später for line in lines: tun, durchlaufen Sie nicht Zeile für Zeile, sondern iterieren jeweils ein Zeichen.

Probieren Sie split aus, bevor Sie das Objekt durchlaufen. Ich schlage auch vor, seinen Namen zu ändern, damit er seinen Inhalt besser beschreibt.

with open(complete_filename, 'r') as provisioning_file: 
    text= provisioning_file.read() 
    # if the old_name is in this file 
    if old_name in text: 
    file_found = 1 
    with open(complete_filename + '.new', 'w') as new_provisioning_file: 
     for line in text.split("\n"): 
     line = line.replace(old_name, new_name) 
     new_provisioning_file.write(line + "\n") 

Edit: alternativer Ansatz:

old_name = 'Some User' 
new_name = 'New User' 

with open(complete_filename, 'r') as provisioning_file: 
    lines = provisioning_file.readlines() 
    # if the old_name is in this file 
    if any(old_name in line for line in lines): 
    file_found = 1 
    with open(complete_filename + '.new', 'w') as new_provisioning_file: 
     for line in lines: 
     line = line.replace(old_name, new_name) 
     new_provisioning_file.write(line) 
+0

Dank! Das macht Sinn. Ich denke, dann wäre eine Alternative "lines = provisioning_file.readlines()"? Wäre das eine andere Art zu lösen? und dann iterieren, wie ich schon bin. – btongeorge

+0

Ja, und in der Tat, das ist vielleicht vorzuziehen, da Sie dann beim Schreiben nicht neu schreiben müssen. Aber Sie müssten Ihre Bedingung an "falls vorhanden" ändern (alter_name in Zeile für Zeile in Zeilen), da 'in' keinen Teilabgleich am Inhalt einer Liste vornimmt. (ex. '" a "in [" ab "," cd "]' ergibt False) – Kevin

+0

Ich habe das versucht, habe aber einen Syntaxfehler auf dem konditionellen, jede Chance, dass Sie mir dies in einem Schnipsel im Kontext zeigen könnten? – btongeorge