Erste Schritte mit Regular Expressions

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.
CrzDivi
User
Beiträge: 5
Registriert: Dienstag 10. Juni 2008, 08:04

Erste Schritte mit Regular Expressions

Beitragvon CrzDivi » Dienstag 17. Juni 2008, 13:14

Hallo,

steige gerade in Python ein und es fängt sogar an Spass zu machen. :o)

Versuche mich gerade an einem kleinen Converter, es sollen Dateien von DokuWiki in HTML umgewandelt werden, villeicht später auch wieder zurück.

Für den, der es nicht kennt, die Formatierung von Dokuwiki

Code: Alles auswählen

====== Ueberschrift 1======
===== Ueberschrift 2=====
==== Ueberschrift 3====
=== Ueberschrift 4===
== Ueberschrift 5 ==

  * Eine
  * Aufzählung

  - Mit
  - Nummerierung

|Eine|Tabelle|
| | |
| | |


Ich wollte jetzt die ====== Ueberschrift 1====== per Regular Expression in <h1>Ueberschrift 1</h1> umwandeln.
Probier da schon eine Weile rum. Irgendwie wird das aber nicht. Komme ich überhaupt mit den Reg. Exp. weiter, oder muss das alles von hand coden?


Dann villeicht, nochmal ob mein Ansatz überhaupt richtig ist.

clhandler kümmert sich um die Kommandozeile
Aufgerufen wird das ganze mit

dokuwiki2html -v -f dokuwikidatei

Code: Alles auswählen

import os
from re import *

from about import about
from clhandler import clh

class MainApp (object) :
    def __init__(self):
        self.clh = clh('dokuwiki2html.py')
        self.about = about()

        if self.clh.opt.verbose : print self.about.getAppVersion()

        if self.clh.opt.file > '': # check if .file is empty
            if os.path.exists(self.clh.opt.file ): # check if file exists
               
                if self.clh.opt.verbose : print self.clh.opt.file
                dkw_file = open(self.clh.opt.file,'r')
               
                dkw_text = dkw_file.read()
                dkw_file.close

                if self.clh.opt.verbose:
                    print "DKWFile Content:"
                    print dkw_text

                rexp_list = (("(======)(======)","(=====).(=====)"),
                             ("<h1>.</h1>",'<h2>.<h2>'))

                html_text = dkw_text
               
                for i in range(len(rexp_list[0])):
                    rexp=compile(rexp_list[0][i])

                    if self.clh.opt.verbose: print i, rexp_list[0][i], rexp_list[1][i]

                    html_text = rexp.sub(rexp_list[1][i],html_text)                 
                   

                if self.clh.opt.verbose: print html_text

                html_file = open(self.clh.opt.file + '.html','w')
                html_file.write(str(html_text))
                html_file.close
               
            else : print self.clh.opt.file, "Datei nicht vorhanden"
        elif self.clh.opt.verbose : print "Keine Datei angegeben"

dokuwiki2html = MainApp()
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Re: Erste Schritte mit Regular Expressions

Beitragvon Leonidas » Dienstag 17. Juni 2008, 13:31

CrzDivi hat geschrieben:Komme ich überhaupt mit den Reg. Exp. weiter, oder muss das alles von hand coden?

Ich würde sagen, dass du mit regulären Ausdrücken vor allem bei verschachtelten Dingen nicht weit kommst. Ich würde da wohl eher einen Parser verwenden.

Schau dir mal Mokuwiki an, das ist ein Parser für Dokuwiki-Syntax, der es dann für MoinMoin aufbereitet.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
CrzDivi
User
Beiträge: 5
Registriert: Dienstag 10. Juni 2008, 08:04

Beitragvon CrzDivi » Dienstag 17. Juni 2008, 13:59

danke. hmm, hatte sowas schon befürchtet.

dann werd ich mal den code von Mokuwiki und vom DokuWiki genauer anschauen und dann hoffentlich zu einer sauberen eigenen Lösung kommen.
BlackJack

Beitragvon BlackJack » Dienstag 17. Juni 2008, 14:21

@CrzDivi: Das Programm kommt übrigens prima ohne eine Klasse aus, die einfach nur eine verkleidete Main-Funktion ist.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Freitag 20. Juni 2008, 12:42

Die gezeigte Syntax ist einfach genug, um sie mit regulären Ausdrücken zu bearbeiten. Ich sehe da nichts, was zählen oder verschachteln müsste - etwas, das reguläre Ausdrücke nicht können sondern wo man einen rekursiven Parser bräuchte.

Die Überschriften könnte man Zeile für Zeile so umwandeln:

Code: Alles auswählen

import re

line = re.sub("^======(.*)======$", "<h1>\\1</h1>", line)

Die Tabellen werden etwas komplizierter, hier würde ich empfehlen, zwei Ersetzungen zu schachteln

Code: Alles auswählen

def r(m):
  return "<table><tr><td>" + re.sub("\\|", "</td><td>", m.group(1)) + "</td></tr></table>"

line = re.sub("^\\|(.*)\\|$", r, line)

In einem späteren Schritt muss man dann aus einem aus allen Zeilen zusammengesetzten String noch alle aneinandergrenzenden "</table><table>" entfernen.

Natürlich könnte man auch einen Parser verwenden, dies wäre eine mögliche Grammatik:

Code: Alles auswählen

document = {heading | table | enumeration | paragraph | lineend}
heading = (h1 | h2 | ...) lineend
h1 = "======" text "======"
h2 = "=====" text "====="
table = trow {trow}
trow = "|" text {"|" text} "|" lineend
enumeration = eitem {eitem}
eitem = "  * " text lineend {"    " text lineend}
paragraph = text lineend { text lineend}
text = <kein leerzeichen oder "|" oder "=" oder "\n"> {<kein "\n">}
lineend = "\n"

Diese Grammatik schachtelt nicht Aufzählungen und erlaubt auch keine Aufzählungen oder Überschriften in Tabellen. Könnte man aber entsprechend erweitern, denke ich.

Stefan

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder