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

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
Benutzeravatar
Mapache23
User
Beiträge: 7
Registriert: Mittwoch 8. Februar 2012, 09:07

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
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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. :)
Benutzeravatar
Mapache23
User
Beiträge: 7
Registriert: Mittwoch 8. Februar 2012, 09:07

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.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ganz genau. Die (unerwünschte) Interpretation ist dann ja bereits erfolgt. Außerdem sieht's recht bescheiden aus. ;)
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ü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:
Benutzeravatar
Mapache23
User
Beiträge: 7
Registriert: Mittwoch 8. Februar 2012, 09:07

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
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Mapache23
User
Beiträge: 7
Registriert: Mittwoch 8. Februar 2012, 09:07

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.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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