Seite 1 von 1

re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 09:15
von Mapache23
Ich habe eine Problem mit re.sub und Variablen zur Rückreferenzierung wie "\1" oder "\2".
Wenn ich diese aus meinen zuvor definierten Listen (replacements) nehme, dann wurde das "\1" bereits direkt interpretiert.

Code: Alles auswählen

replacements = [
	['<p>[\s]+([0-9]+\. Kapitel.*?)<\/p>', '<h2>\1</h2>'],
	['<p>[\s]+(Vorwort|Schlusswort|Prolog|Epilog|Danksagung)<\/p>', '<h2>\1</h2>']
]
...

	for rep in replacements:
			newcontent = re.sub(rep[0], rep[1], content, 0, re.MULTILINE)

Aus <p>Vorwort</p> wird dann <h2>SOH</h2>, also Müll an der Stelle des Vorworts, weil er das \1 zum Zeitpunkt des erzeugens des Strings nicht zuordnen konnte.
Wie kann ich dann das Replacement mit Variablen ausführen, ohne dass direkt beim Erzeugen des Strings das "\1" interpretiert wird?

Dankee

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 09:37
von snafu
Indem du ein `r` davorsetzt, um einen sogenannten Raw-String zu erzeugen. Beispiel:

Code: Alles auswählen

r'<h2>\1</h2>'
Solltest du dir für reguläre Ausdrücke am besten grundsätzlich angewöhnen. :)

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 09:42
von Mapache23
Arrr - natürlich!
Danke fürs Augen öffnen!

Ich hatte es unten schon so:

Code: Alles auswählen

newcontent = re.sub(r"%s" % rep[0], r"%s" % rep[1], content, 0, re.MULTILINE)
Aber das hatte dann natürlich keinen Effekt mehr.

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 10:22
von snafu
Ganz genau. Die (unerwünschte) Interpretation ist dann ja bereits erfolgt. Außerdem sieht's recht bescheiden aus. ;)

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 10:24
von snafu
Übrigens, als kleine Anmerkung: Ich würde die `replacements` zwar als Liste machen, aber dann eher ein Tupel nehmen bei den Angaben für `(pattern, repl)`. Passt IMHO von der Datenstruktur/Intention her besser, auch wenn's bei der Anwendung keinen Unterschied macht.

Und dann halt ein:

Code: Alles auswählen

for (pattern, repl) in replacements:

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 10:29
von Mapache23
Ok, danke!

Ich komme von Perl und muss das hier nur ausnahmsweise in Python umsetzen. Finde Python aber sehr angenehm.
Der Unterschied vom Tupel zur Liste ist, dass es unveränderbar zur Laufzeit des Programms ist, richtig?

Grüße

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 10:34
von snafu
Mapache23 hat geschrieben:Der Unterschied vom Tupel zur Liste ist, dass es unveränderbar zur Laufzeit des Programms ist, richtig?
Richtig. Dementsprechend bietet es sich in Situationen, wo es um eine feste Anordung geht, eigentlich ganz gut an.

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 12:54
von Hyperion
Da das ganze doch stark nach HTML aussieht: Wäre die Verwendung eines HTML-Parsers (etwa lxml.html) nicht die einfachere und stabilere Lösung?

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 12:57
von Mapache23
Es geht genau genommen um automatische Ersetzungen in EPUB Files, die im Grunde aus HTML aufgebaut sind.
Ich werde mal in einer ruhigen Minute drüber nachdenken.

Re: re.sub mit Variablen und Rückreferenzen wie \1

Verfasst: Mittwoch 8. Februar 2012, 13:12
von snafu
Vielleicht willst du auch mal nen Blick auf das externe Modul epub werfen. Ich habe das noch nicht benutzt, sondern nur mal spaßeshalber eine Suche zum Thema gemacht. Die Doku dazu ist dummerweise wohl nur auf franözisch verfügbar. Jedoch sind die Funktionen alle in englisch benannt und es sind auch Beispiele dabei, sodass man wahrscheinlich ganz gut zurechtkommen würde. Unter anderem gibts ein Beispiel, um ein `.epub`-File zu lesen und sich dann ein Kapitel rauszusuchen (Link). Ggf kannst du damit ja schon was anfangen. :)

//edit: Wobei, da scheint's wirklich nur um's Lesen zu gehen. Du willst ja was ersetzen.