Seite 1 von 1
komplexe regexp, einfacher möglich?
Verfasst: Samstag 24. März 2007, 15:05
von apollo13
Die folgende Regexp matcht alle Headlines von h1 bis h5 (wobei h1 = '=' und h5 = '=====').
Syntax für erfolgreichen match:
Code: Alles auswählen
= Ich bin ein h1 =
== Ich bin ein h2 mit whitespaces davor und danach ==
Der Code:
Code: Alles auswählen
import re
rawstr = r"""^\s*(?P<level>={1,5})(?P<inhalt>(?!=).+(?<!=))(?P=level)\s*$"""
matchstr = """= 342 =
== asdfd =
==fs df===
=== asd ===
== asd==asd == """
# method 2: using search function (w/ external flags)
match_obj = re.search(rawstr, matchstr, re.MULTILINE)
# Retrieve group(s) by name
level = match_obj.group('level')
inhalt = match_obj.group('inhalt')
print level,inhalt
Kann ich die Regex noch etwas besser machen (performance, lesbarkeit etc...)
Der Sinn davon ist diese Regex als lexer.match für Tekisuto zu verwende

Funktioniert bis jetzt gut, Hut ab @blackbird für diesen genialen Parser!
MfG apollo13
EDIT:// Hmm, kA wie ich da noch die anderen matches anzeigen kann (ist nur aus Kodos rauskopiert. Nur den Testcode, nicht die Regex, die ist von mir)
Verfasst: Samstag 24. März 2007, 15:49
von EnTeQuAk
Du weißt aber, das Tekisuto noch kein bisschen released wurde, ja?
Ansonsten für verschiedene Regular Expressions kannst du mal hier schauen:
http://daucms.de/trac/browser/daucms/ut ... er.py#L136
vielleicht hilft dir das ein wenig weiter
Übrigens ist Tekisuto kein Parser sondern ist (oder soll werden) ein Framework, um sich selber Parser zu generieren. Tekisuto übernimmt zZ nur die Rolle eines Lexers.
(sollte ich falsch liegen blackbird, sag bescheid

)
MfG EnTeQuAk
Verfasst: Samstag 24. März 2007, 16:29
von apollo13
Mein Fehler, meinte natürlich lexer.
Nicht fertig und dennoch sehr gut
achja deine headline regex bekommt kleine Probleme mit sowas:
=== asd ====
der content-match wäre dann 'asd ='. Um das zu verhinder ist meine ja so komplex
Nachdem Tekisuto ja so perfekt lext, schaut mein Parser (oder was auch immer) nur mehr so aus:
Code: Alles auswählen
def wikify(text):
"""
Parses the input and returns the new string
"""
mein_rep = {
'wiki/italic/start':'<i>',
'wiki/italic/end':'</i>',
# snipp
'wiki/text':(lambda x: x),
'wiki/heading':(lambda x: '<h%s>%s</h%s>' % (x['level'],x['inhalt'],x['level']))
}
erg = ''
for token in WikiLexer(text):
if (mein_rep.has_key(token.name) and callable(mein_rep[token.name])):
erg = erg + mein_rep[token.name](token.data)
elif mein_rep.has_key(token.name):
erg = erg + mein_rep[token.name]
return erg
Verfasst: Samstag 24. März 2007, 17:05
von EnTeQuAk
achja deine headline regex bekommt kleine Probleme mit sowas:
=== asd ====
der content-match wäre dann 'asd ='. Um das zu verhinder ist meine ja so komplex
Für mich ist das auch richtig. Denn... willst du das letzte '=' als weiteres '<h1>' ansehen?
Wenn ja, spielst du dem Benutzer eventuell einen starken Streich
Oder verstehe ich dich jetzt falsch?
btw: schau dir ma die Beispiele von Tekisuto an... liegen auch im Trunk

da hast du wunderbare Beispiele, wie bestimmte Sachen gelößt werden können.
MfG EnTeQuAk
Re: komplexe regexp, einfacher möglich?
Verfasst: Samstag 24. März 2007, 23:30
von PmanX
apollo13 hat geschrieben:Die folgende Regexp matcht alle Headlines von h1 bis h5 (wobei h1 = '=' und h5 = '=====').
...
match_obj = re.search(rawstr, matchstr, re.MULTILINE)
Soll sich die Headline über mehrer Zeilen erstrecken?
re.MULTILINE überdenken.
Code: Alles auswählen
(?P<inhalt>(?!=).+(?<!=))
# wuerde ich so schreiben
(?<inhalt>[^=]+)
Verfasst: Sonntag 25. März 2007, 11:20
von apollo13
EnTeQuAk hat geschrieben:
achja deine headline regex bekommt kleine Probleme mit sowas:
=== asd ====
der content-match wäre dann 'asd ='. Um das zu verhinder ist meine ja so komplex
Für mich ist das auch richtig. Denn... willst du das letzte '=' als weiteres '<h1>' ansehen?
Wenn ja, spielst du dem Benutzer eventuell einen starken Streich
Oder verstehe ich dich jetzt falsch?
Nein, das sehe ich durch meine Regex nicht als solches an, es wird einfach nicht als Heading erkannt, sondern nur als === asd ==== ausgegeben.
Wobei es wahrscheinlich etwas zu viel des guten ist, aber dieses Problem hat mir sehr geholfen Regex besser zu verstehn
EnTeQuAk hat geschrieben:
btw: schau dir ma die Beispiele von Tekisuto an... liegen auch im Trunk

da hast du wunderbare Beispiele, wie bestimmte Sachen gelößt werden können.
MfG EnTeQuAk
Ja die hab ich dafür verwendet, um die Arbeitsweise von Tekisuto zu verstehen
PmanX hat geschrieben:apollo13 hat geschrieben:Die folgende Regexp matcht alle Headlines von h1 bis h5 (wobei h1 = '=' und h5 = '=====').
...
match_obj = re.search(rawstr, matchstr, re.MULTILINE)
Soll sich die Headline über mehrer Zeilen erstrecken?
re.MULTILINE überdenken.
MULTILINE ist in diesem Fall nur für kodos, damit ich einen searchstring mit mehreren Zeilen testen kann.
Siehe
http://docs.python.org/lib/node46.html eben damit die Regexp über alle Zeilen läuft und ich Zeile für Zeile auf ein richtiges/falsches heading testen kann, sonst müsste ich immer die erste Zeile abändern und wenn ich in der Regex was falsch mache weiß ich nimmer ob das erste (gelöschte) noch existiert.
PmanX hat geschrieben:
Code: Alles auswählen
(?P<inhalt>(?!=).+(?<!=))
# wuerde ich so schreiben
(?<inhalt>[^=]+)
Nö dann dürfte in der Überschrift kein = Zeichen stehn, ob sich so aufwendig lohnt oder nicht, siehe weiter oben...
MfG apollo13
Verfasst: Sonntag 25. März 2007, 11:58
von PmanX
apollo13 hat geschrieben:MULTILINE ist in diesem Fall nur für kodos, damit ich einen searchstring mit mehreren Zeilen testen kann.
Siehe
http://docs.python.org/lib/node46.html eben damit die Regexp über alle Zeilen läuft und ich Zeile für Zeile auf ein richtiges/falsches heading testen kann, sonst müsste ich immer die erste Zeile abändern und wenn ich in der Regex was falsch mache weiß ich nimmer ob das erste (gelöschte) noch existiert.
PmanX hat geschrieben:
Code: Alles auswählen
(?P<inhalt>(?!=).+(?<!=))
# wuerde ich so schreiben
(?<inhalt>[^=]+)
Nö dann dürfte in der Überschrift kein = Zeichen stehn, ob sich so aufwendig lohnt oder nicht, siehe weiter oben...
Ich würde eine RegEx auf einen speziellen Fall erstellen und kann mir nicht vorstellen, dass eine Überschrift über zwei Zeilen laufen soll.
Du läßt doch nur "=" im Zentrum des Strings zu

Wenn das sinnvoll ist ..
Gruß P.
Verfasst: Sonntag 25. März 2007, 12:04
von apollo13
Sie geht doch nur über eine Zeile, Ich glaube du (oder ich?!) hast multiline nicht ganz verstanden.
Das nimmt doch bei einem String mit mehreren Zeilen jedes newline als ^ bzw $ und somit bekomme ich für jede Zeile einen match oder eben keinen (wie gesagt nur zum Testen ob die RegEx funktioniert. In Tekisuto wird sowieso mit einzelnen Zeilen gearbeitet)
Wäre also so als würde ich die RegEx nach der Reihe mit den einzelnen Zeilen füttern.
Klar ein '=' am Rand des Strings ist etwas kompliziert, ohne Trennung zur headline *gg*
Wenn das sinnvoll ist ..
Learning by doing, wie soll ich sonst das Buch "Mastering Regular Expressions" verstehn

Und nen BBCode/Wiki Parser war das Erste was mir einfiel um solche RegExes auszutesten.
Verfasst: Sonntag 25. März 2007, 12:51
von PmanX
Wenn Du Zeilenweise arbeitest, willst(brauchst) Du Multiline nicht.
Wenn ein String Newlines enthält, will man ihn möglicherweise als Sammlung logische Zeilen betrachten.
_^_ paßt dann auf den Anfang jeder logischen Zeile und _$_ auf das Ende. Nicht mehr, nicht weniger.
Gruß P.
Verfasst: Sonntag 25. März 2007, 13:10
von apollo13
Und gerade deshalb verwende ich zum Testen mit Kodos multiline, sonst bekomme ich nur ein match, nämlich das Erste.
Wie dem auch sei es funktioniert wie es soll (ohne Multiline und mit Tekisuto)

Verfasst: Sonntag 25. März 2007, 14:22
von BlackJack
Also ich finde ``=`` in Überschriften sollte erlaubt sein. Wenn man zum Beispiel einen Text über Python schreibt, liegt eine Überschrift wie "== Der Unterschied zwischen `==` und `is` ==" durchaus im Bereich des Wahrscheinlichen.
Verfasst: Sonntag 25. März 2007, 17:34
von PmanX
Dann würde ich die Syntax derartig einschränken.
Code: Alles auswählen
cre = re.compile(r'(?P<bound>^={2,5})([ ].*?[ ])(?P=bound)$')
Verfasst: Sonntag 25. März 2007, 17:45
von apollo13
Könnte man machen, dann wäre das Leerzeichen allerdings zwinged, das würde ich nervig finden...
Verfasst: Sonntag 25. März 2007, 17:49
von EnTeQuAk
Also ich finde ``=`` in Überschriften sollte erlaubt sein. Wenn man zum Beispiel einen Text über Python schreibt, liegt eine Überschrift wie "== Der Unterschied zwischen `==` und `is` ==" durchaus im Bereich des Wahrscheinlichen.
Könnte man mit dem alltbekannten 'escapen' realisieren.
mit folgender Regex könnte man bestimmte Headlines 'escapen' und sie vorm ersetzen fernhalten:
Code: Alles auswählen
cre = re.compile(r'!?(?P<bound>={2,5})(.*)(?P=bound)')
Wobei hier die Bindung an den Satzanfang fehlt...
MfG EnTeQuAk
Verfasst: Sonntag 25. März 2007, 18:22
von PmanX
apollo13 hat geschrieben:Könnte man machen, dann wäre das Leerzeichen allerdings zwinged, das würde ich nervig finden...
Ich würde Wildwuchs nervig finden

Verfasst: Sonntag 25. März 2007, 19:00
von apollo13
Hehe jeder wie er meint und so ist es auch gut
