Textbausteine

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
steffan
User
Beiträge: 2
Registriert: Freitag 30. Oktober 2009, 16:01

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
Benutzeravatar
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:

Code: Alles auswählen

// 'bar' auf globaler Ebene
int bar = 1;

void foo() {
    // noch eine Variable namens "bar"
    int bar = 42;
}
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.

Code: Alles auswählen

int bar = 1;
// hier müßte bar ja auch durch den neuen Namen ersetz werden!
foo(bar);
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".
Zuletzt geändert von Hyperion am Freitag 30. Oktober 2009, 17:10, insgesamt 1-mal geändert.
Benutzeravatar
SigMA
User
Beiträge: 181
Registriert: Sonntag 4. April 2004, 13:27
Wohnort: Freiburg
Kontaktdaten:

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"
Öffne Datei,
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
BlackJack

@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!?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

SigMA hat geschrieben:Q&D aber so sollte es gehen^^
Nein, so geht es ganz sicher nicht.
steffan
User
Beiträge: 2
Registriert: Freitag 30. Oktober 2009, 16:01

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".
Zuerst beschäftige ich mich nur mit Suchen/Ersetzen. Da werde ich mich jetzt über geeignete Tools informieren.

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.
BlackJack

@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:

Code: Alles auswählen

In [186]: t = string.Template('$name=2*4;')

In [187]: t.substitute(name='Window')
Out[187]: 'Window=2*4;'
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Wenn du da deine Konstrukte bzw. Templates (oder was auch immer) sinnvoll wählst, reicht da einfaches Suchen und Ersetzen, also

Code: Alles auswählen

str.replace('old', 'new')
Oder besser du nimmst die ``str.format`` Methode (Python >= 2.6):

Code: Alles auswählen

template = 'int {var_name} = 5;'
output = template.format(var_name= 'new_name')
Oder du verwendest die Template-Klasse:
http://docs.python.org/dev/library/stri ... te-strings
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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)
Stefan
Antworten