Seite 1 von 2

Reguläre Ausdrücke

Verfasst: Montag 29. Oktober 2007, 10:05
von xpaffx
Hi Leute,

ich habe ein kleines Problem mit einem regulären Ausdruck, ich möchte folgende Strings substituieren:

"FId_*" zu "FId_unused" und

FESTWERT DFES_Cls.*Wert 1.0 zu FESTWERT DFES_Cls.*Wert 2.0

Das heißt ich will alle ändern, beim ersten Ausdruck machen die Anführungszeichen Probleme, ja die sind in der TEXT-Datei drin, und auch ein wichtiges Kriterium, beim zweiten Ausdruck klappt es auch nicht...was mache ich nur falsch?

Code: Alles auswählen

import re
from sys import *

# -------------------------------------------------------------------------------------
# --- Name     : readFromTextData
# --- Funktion : Liest eine Datei ein und gibt die Zeilen als Liste zurueck
# --- Parameter: path : Pfad der Datei
# --- Rueckgabe :Zeilen als Liste
# -------------------------------------------------------------------------------------
def readFromTextData( path ):
    fid = open(path, 'r')
    #lines_ = fid.readlines()
    lines_ = fid.read()
    fid.close()
    return lines_


# Hauptprogramm das den Parameter (den Pfad zur DCM ) entgegennimmt
if  __name__ == '__main__':
#print len(argv)
    if len(argv) == 1:
	print "usage: ersetzung DCM_FIle" 
    else:
        worktxt = re.sub('\"FId_*\"', '\"FId_UNUSED\"', readFromTextData(argv[1]))
        #print worktxt
#        print (re.search("FId_*",readFromTextData(argv[1]))).group()
        worktxt = re.sub("FESTWERT DFES_Cls*WERT 1.0","FESTWERT DFES_Cls*WERT 2.0", worktxt)
	outF = open("ersetzt.DCM", "w")
        outF.write(worktxt)
        outF.close()


Verfasst: Montag 29. Oktober 2007, 10:12
von Leonidas
Und wozu brauchst du da reguläre Ausdrücke? Ein simples String-Replace tut es in diesem Fall doch auch.

Verfasst: Montag 29. Oktober 2007, 10:22
von xpaffx
funktionieren denn da die metazeichen auch?
Die * sind ja sehr relevant da ich nicht immer weiß wieviele Zeichen dazwischen liegen

Verfasst: Montag 29. Oktober 2007, 10:34
von Leonidas
xpaffx hat geschrieben:funktionieren denn da die metazeichen auch?
Nein, tun sie nicht.
Aber so wie du sie im Beispielcode verwendest match du eine beliebige Anzahl von Unterstrichen (`FId_*`) und eine beliebige Anzahl von s (`FESTWERT DFES_Cls*WERT 1.0`). Insbesondere beim letzten sagst du erst dass du `FESTWERT DFES_Cls.*Wert 1.0` ersetzen willst, aber dann`FESTWERT DFES_Cls*Wert 1.0` ersetzt...

Verfasst: Montag 29. Oktober 2007, 10:36
von BlackJack
@xpaffx: Dann beschreibe Dein Problem nochmal genauer und zwar so dass *genau* klar ist was literale Zeichen und was Platzhalter sind. Wenn Du sagst "FId_*" soll zu "FId_unused" werden, ist das Sternchen dann ein Sternchen oder ein Platzhalter für beliebige Zeichen (ausser vielleicht Leerzeichen, Ziffern, etc.)?

Wenn Du Dein Problem auf diese Weise *genau* beschreibst, löst Du das ganze vielleicht sogar selbst. Weil Du dann im Grunde einen regulären Ausdruck beschreibst, den Du haben möchtest. :-)

Verfasst: Montag 29. Oktober 2007, 11:00
von xpaffx
Also diese "*" stellen beliebige Zeichen dar, das können Buchstaben, Zahlen, Sonderzeichen, Zeilenumbrüche usw. einer beliebigen Länge sein.

Ich weiß eben nicht wie die FId's vorher aussehen , das selbe gilt für das zweite Beispiel...dort können ebenso beliebige zeilen davor stehen ...

Verfasst: Montag 29. Oktober 2007, 11:36
von BlackJack
Tja dann liegt das Problem daran das ein '*' in regulären Ausdrücken nicht für beliebige Zeichen steht, sondern den Teil der davor steht modifiziert. '*' bedeutet 0 oder mehrfache Vorkommen des Teils der vor dem '*' steht.

Dein erstes Muster muss also so aussehen '"FId_.*?"'. Das ist '"FId_' gefolgt von 0 oder mehr beliebigen Zeichen. Das '.' steht für ein beliebiges Zeichen, das '*' für das 0 oder mehr. Das '?' brauchst Du noch weil reguläre Ausdrücke normalerweise "greedy" sind und versuchen soviel wie möglich zu matchen. In den beliebigen Zeichen ('.') ist auch das " enthalten, wenn davon also mehrere in der Zeile vorkommen, wird sonst bis zum letzen gematcht.

Und wenn Du Teile aus dem Muster in der Ersetzung haben willst, dann kannst Du dort nicht einfach wieder ein Muster angeben. Die Zeichenkette für die Ersetzung wird ja nicht auf die Eingabe angewendet. Dort musst Du eine Referenz auf die Gruppe im Suchmuster angeben. Dass heisst Du musst das dort auch mit Klammern gruppieren.

Der Ausdruck sieht dann analog zum ersten Beispiel so aus 'FESTWERT DFES_Cls(.*?)WERT 1.0'. Die Klammern sorgen dafür, dass das was dort passt in einer Gruppe gespeichert wird. Die sind durchnummeriert. Das ist also die erste Gruppe und die kann man in der Ersetzungszeichenkette mit r'\1' einfügen: r'FESTWERT DFES_Cls\1WERT 2.0'

Wenn Du so etwas öfter machen musst, solltest Du mal ein gutes Tutorial zu regulären Ausdrücken durcharbeiten.

Verfasst: Montag 29. Oktober 2007, 12:04
von xpaffx
Danke, jetzt ist es natürlich klar wieso das ganze nicht geklappt hat.

Nur leider geht das zweite immer noch nicht obwohl ich mich an deine Anweisungen gehalten habe:

Code: Alles auswählen

        worktxt = re.sub("FESTWERT DFES_Cls(.*?)WERT 1.0", r'FESTWERT DFES_Cls\1WERT 2.0', worktxt)

Verfasst: Montag 29. Oktober 2007, 12:08
von BlackJack
Also damit wird bei mir 'FESTWERT DFES_ClsFooWERT 1.0' zu 'FESTWERT DFES_ClsFooWERT 2.0'.

Was passiert bei Dir? Und wie sieht denn die Eingabe genau aus? Du hast in Deinen Beschreibungen mal 'WERT' und mal 'Wert' geschrieben. Das macht natürlich einen Unterschied.

Verfasst: Montag 29. Oktober 2007, 12:21
von xpaffx
Also die Datei hat z.B. den Inhalt(Auszug):

FESTWERT DFES_Cls.DFC_ACCIaDesMax_C
LANGNAME "DFES / Fehlerklasse fuer Pruefung DFC_ACCIaDesMax"
FUNKTION dfes_class_auto
EINHEIT_W "-"
WERT 1.0
END

Und danach sieht sie immer noch genauso aus, das mit dem UnUsed hat jedoch geklappt

Verfasst: Montag 29. Oktober 2007, 12:54
von xpaffx
probleme bereiten anscheinend die zeilenumbrüche...ansonsten geht es nämlich...weiß einer wieso es nicht geht oder besser wie es geht?!

Verfasst: Montag 29. Oktober 2007, 13:41
von BlackJack
Der Punkt trifft normalerweise nicht auf den Zeilenwechsel zu. Dazu muss der reguläre Ausdruck mit `re.DOTALL` als Flag übersetzt werden. Das kann man bei `re.sub()` nicht machen, also müsstest Du den Ausdruck mit `re.compile()` übersetzen und von dem Objekt dann die `sub()`-Methode verwenden.

Verfasst: Montag 29. Oktober 2007, 13:42
von Jona
du könntest die datei auch zeilenweise einlesen und bearbeiten.

Verfasst: Montag 29. Oktober 2007, 13:45
von xpaffx
ja klar aber es muss doch so jetzt gehen ...bis auf diesen kleinen fehler mit den zeilenumbrüchen??

Verfasst: Montag 29. Oktober 2007, 13:52
von HWK
'1.0' und '2.0' müssten noch in '1\.0' und '2\.0' umgewandelt werden, sonst steht der Punkt ja wieder für ein beliebiges Zeichen.
MfG
HWK

Verfasst: Montag 29. Oktober 2007, 13:57
von xpaffx
Nein das hat nicht gereicht, also hier folgendes müsste doch eigentlich gehen...tut es aber nicht:

Code: Alles auswählen

        worktxt = re.sub("FESTWERT DFES_Cls(.*?)WERT 1\.0", r'FESTWERT DFES_Cls\1WERT 2\.0','FESTWERT DFES_Cls\nhi\nWERT 1.0')

Verfasst: Montag 29. Oktober 2007, 14:21
von Rebecca
Hast du BlackJacks Rat befolgt?

Verfasst: Montag 29. Oktober 2007, 14:50
von xpaffx
oh die antwort wurde vorhin in meinem browser nicht dargestellt...seltsam danke ist jetzt klar teste es morgen ;)

Verfasst: Montag 5. November 2007, 10:44
von xpaffx
danke sehr, es hat geklappt!!! python rulez ;p

Verfasst: Mittwoch 7. November 2007, 16:16
von mulder
moin!

ich habs jetz (wiedermal) lange versucht und denke das ich einfach mal den wald vor lauter baeumen nicht seh! .. :oops:

ich moechte einen re mit einer variable "fuellen" und dann einen findall machen!

aber der pattern will mit ueberhaupt nicht gelingen!

Code: Alles auswählen

        PATTERN = re.compile(r'(NAME;.*)')
        PATTERN =  "r\'" + NAME + ";.*\'"
das sind meine beiden letzten erfolglosen versuche! .. :cry:

also NAME ist nen varianlen name. der versuch mit dem compile sieht nicht nur hilflos aus ... er ist es auch .. :oops: ne also .. ich hab da noch nicht die richtige syntax zusammen!...