hallo,
ich möchte ein Programm schreiben, bei dem ich in vorhanden C-Code Namen austausche.
Als Beispiel:
in einer textdatei (oder sonstigen Datei) steht Code wie...
Name=2*4; //Name ist nur ein Platzhalter
jetzt will ich mit Python den Code lesen, "Name" ersetzten und den neuen Code in eine .c-Datei schreiben. Die C-Datei könnte dann so aussehen:
Window=2*4; //"Name" wurde durch "Window" ersetzt
Ich bin neuling in Python und hab jetzt ein Turorium hinter mir, aber ich sehe noch nicht wie ich das lösen kann.
Was für Befehle würden sich da anbieten?
danke
Textbausteine
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Hier kommt es nicht auf "Befehle" an, sondern zunächst einmal auf die geeigneten Strategie.
Refactoring ist nicht ganz so trivial wie man zunächst denken würde:
Was würde passieren, wenn man nur nach "bar =" suchen würde? Man würde ja beide finden und entsprechend ersetzen - dabei sind das ja zwei vollkommen unterschiedliche Bezeichner.
Für die einfache Lösung, die das obige Problem vermutlich nicht lösen können wird, könntest Du über einen einfachen RegExp nach dem Konstrukt "<Bezeichner><beliebige Leerzeichen><=>" suchen.
Willst Du die unterschiedlichen Namen in unterschiedlichen Code-Blöcken auseinander halten, so müßtest Du die Datei mit einem Parser parsen und dann die Semantik auswerten. Das ist sicherlich ungleich komplexer!
Hinzu kommt noch die Problematik, dass Du ja nicht nur die Zuweisung ändern müßtest, sondern auch die Stellen, an denen ein Bezeichner als Parameter übergeben wird.
Was genau planst Du denn? Viele Editoren und IDEs berherrschen das relativ gut. Und simples Suchen / Ersetzen kann man auch mit jedem Editor oder auf Shell-Ebene mit Tools wie "sed".
Refactoring ist nicht ganz so trivial wie man zunächst denken würde:
Code: Alles auswählen
// 'bar' auf globaler Ebene
int bar = 1;
void foo() {
// noch eine Variable namens "bar"
int bar = 42;
}
Für die einfache Lösung, die das obige Problem vermutlich nicht lösen können wird, könntest Du über einen einfachen RegExp nach dem Konstrukt "<Bezeichner><beliebige Leerzeichen><=>" suchen.
Willst Du die unterschiedlichen Namen in unterschiedlichen Code-Blöcken auseinander halten, so müßtest Du die Datei mit einem Parser parsen und dann die Semantik auswerten. Das ist sicherlich ungleich komplexer!
Hinzu kommt noch die Problematik, dass Du ja nicht nur die Zuweisung ändern müßtest, sondern auch die Stellen, an denen ein Bezeichner als Parameter übergeben wird.
Code: Alles auswählen
int bar = 1;
// hier müßte bar ja auch durch den neuen Namen ersetz werden!
foo(bar);
Zuletzt geändert von Hyperion am Freitag 30. Oktober 2009, 17:10, insgesamt 1-mal geändert.
Code: Alles auswählen
tmp = file(DATEINAME, "rb").read().split("\n")
result = ""
for line in tmp:
line = line.replace(STICHWORT, DURCHWAS_ERSETZEN)
if line: self.result += line+u"\n"
Gehe durch jede Zeile,
Ersetzte in JEDER Zeile STICHWORT durch DURCHWAS_ERSETZEN,
Wenn Die Zeile nicht leer ist, dann füg wieder hinzu,
Neue Datei in '''result''' muss man dann nur noch schreiben
Q&D aber so sollte es gehen^^
Leichtdio.de - Das Kreativ-Blog
http://www.leichtdio.de
http://www.leichtdio.de
@SigMA: OMG was für ein Murks ist dass denn? Man könne auch Zeilenweise über die Datei iterieren statt sie komplett einzulesen, und dann in eine Liste mit Zeilen zu trennen. Zu dem Zeitpunkt hat man die Daten dann gleich doppelt im Speicher. Zeichenketten mit ``+=`` in einer Schleife "aufaddieren" kann eine besch..., nämlich quadratische Laufzeit haben. Wo kommt das `self` her? Und warum willst Du nur reine ASCII-Dateien bearbeiten, die aber trotzdem in Unicode umwandeln!?
Zuerst beschäftige ich mich nur mit Suchen/Ersetzen. Da werde ich mich jetzt über geeignete Tools informieren.Hyperion hat geschrieben: Was genau planst Du denn? Viele Editoren und IDEs berherrschen das relativ gut. Und simples Suchen / Ersetzen kann man auch mit jedem Editor oder auf Shell-Ebene mit Tools wie "sed".
Hintergrund ist...
Ich will einen Code-Generator schreiben. Der Benutzer soll zwischen meinen Code-Konstrukten wählen, dem Konstrukt einen Namen geben und einige weitere Attribute angeben. Das soll der Benutzer in eine XML-Datei schreiben und anhand dieser wird mein Programm den richtigen Code generieren.
@steffan: Dann möchtest Du vielleicht mal die vielen Template-Bibliotheken für Python anschauen, statt da etwas mit suchen und ersetzen zu basteln.
Das simpelste wäre `string.Template` aus der Standardbibliothek:
Das simpelste wäre `string.Template` aus der Standardbibliothek:
Code: Alles auswählen
In [186]: t = string.Template('$name=2*4;')
In [187]: t.substitute(name='Window')
Out[187]: 'Window=2*4;'
Wenn du da deine Konstrukte bzw. Templates (oder was auch immer) sinnvoll wählst, reicht da einfaches Suchen und Ersetzen, also
Oder besser du nimmst die ``str.format`` Methode (Python >= 2.6):
Oder du verwendest die Template-Klasse:
http://docs.python.org/dev/library/stri ... te-strings
Code: Alles auswählen
str.replace('old', 'new')
Code: Alles auswählen
template = 'int {var_name} = 5;'
output = template.format(var_name= 'new_name')
http://docs.python.org/dev/library/stri ... te-strings
Code: Alles auswählen
s = """
int NAME = 4 * 3; // dies wird ersetzt
void bar() {
int a = 3; // dies nicht
}
"""
import re
replacements = {'NAME': 'Window'}
def f(m): return m.group(1) + replacements[m.group(2)]
print re.sub(r"(?m)^(\w+\s+)(\w+)(?=\s*=)", f, s)