f·010406

Improved RegExps, using PCRE

6. April 2001, 10:05:08
Feature
DoneMateese, Fiona

HR Image

Fertig in 3-3.
In 3-2 in allen Efuns bis auf regreplace() aktiv mit patch.

---

Welche Expressions kennt der Driver im Moment?
( ) . * + | $ ^ [ ] \< \> \B

"\\b" "\\t" "\\r" -> werden durchgereicht als '\b' '\t' '\r'

ansonsten wird der \ ignoriert, also "\\x" liefert 'x'

Im Excompat-Modus (unterstuetzt nur regreplace) ist ( ) ein normales
Zeichen und \( \) sind die Klammern.

Gibt es Kollisionen mit den RCREs? 
* \< und \> sind nicht vorhanden. Eventuell kann man diese durch
  \b (word boundary) ersetzen. Emulieren waere moeglich mit \b\w
  sowie \b\W
* ( und ) werden wie im 'normalen' Modus behandelt, excompat muss emuliert
  werden

Wie arbeitet der Driver mit Multilines?
    ^      matcht Stringanfang
    $      matcht Stringende; matcht nicht auf \n vor Stringende
    .      matcht \n; matcht nicht Stringende
    [^x]   matcht auf \n

Dies entspricht etwa /s bei Perl und
PCRE_DOLLAR_ENDONLY | PCRE_DOTALL bei Pcre

----



Zum Regex Kram fiel mir noch ein, dass es schoen waere, wenn man regexp()
auch ohne Array benutzen kann, wenn man nur sehen will ob ein String passt
muss man den zZ via sizeof(regexp(({str}), re)) testen. Je mehr ich
darueber nachdenke, desdo weniger trivial erscheint es mit mit den
PerlREs. Die koennen in Perl naemlich verschiedene Modi haben, die man nun
eigentlich mituebergeben koennen muesste. Ausserdem sollte man auch auf
die Klammerausdruecke zugreifen koennen, dort waere am besten irgendwie
sowas...

  n_regexp(string str, string RE, string parameter).

Wenn 'parameter' nicht gegeben ist, wird der normale endliche Automat des
Muds benutzt. Sonst wird halt der Perl-Automat benutzt, der die Parameter
erhaelt. Wenn die RE gefunden wird lieferts 'wahr' sonst 'unwahr'.
Weiterhin (und deswegen wuerde ich die Efuns trennen dh anders nennen)
waere eine Unterstuertzung fuer die Rueckwaertsreferenzen klasse. Also
was man bei regreplace mit \1 usw erhalten kann. Ich traeume mir vor, dass
ich an n_regexp() nun auch angeben kann, welche Referenzen mich
interessieren und die liefert es dann als Array. (Da das doch sehr anders
ist als regexp() eine andere Efun.)
Also parameter = "ig\1\5\9" oder so ('\'s sollen "\\" sein ;o).


Btw kann man den (nichtdeterministischen) Automaten mit einer Zeile in die
ewigen Jagdgruende schicken ('regular expressions' von oreilly entnommen):

 regexp(({"=XX============================================"}), "X(.+)+X")

Eventuell sollte man in dem FA halt einfach jedem Backtracking eine
eval-cost zuordnen um das zu verhindern (die Laufzeit des Matchens oben
ist propotional pow(2, strlen)). Das waere zB moeglich bei Zeile 1158 des
regexp.c:
                        return MY_TRUE;
                /* Couldn't or didn't -- back up. */
                no--;
+               evals += 5;
+               if (evals > evals_max) regerror("too many backtracks");
                reginput = save + no;
            }

(mit evals und evals_max symbolisch fuer die Kosten). Ich schlage gerade
vor genau DAS als Kriterium zu nehmen, weil das ziemlich sicher soetwas
unendliches erkennt, alles andere kann auch 'viel' werden, aber da kanns
trotzdem gleich fertig sein.
----------

Btw den Automaten kann man (selbstverstaendlich) mit derselben Regex von
letztens in eine 'unendliche' Schleife schicken. Wie man dort dann
nachtraeglich Evalkosten pro Backtrack einbaut *gruebel*...
Uebrigens ist der Pcre-Automat etwa doppelt so schnell bei der Schleife,
20 '=' nach den XX dauern bei mir 2 bzw 4 Sekunden.

----
Hab grad nochmal ein bissl Zeit gefunden und hab mal geschaut ob ich
den rxcache nicht irgendwie mitbenutzen kann. So schwierig scheint das
nicht zu sein, ich muesste nur den Wert von from_ed irgendwie
erweitern, dass man pcre-Ausdruecke erkennen kann.

---
Dann sollte man natuerlich auch in den anderen reg* Funktionen die
perlaehnlichen Ausdruecke verwenden koennen. 'normale' sollten einfach
so zu ersetzen sein, die excompat muesste man ein bissl vorher
anpassen - wenn man einfach fuer alles pcre nehmen will. Ich denke das
ist der einfachste Ansatz anstatt zwei Automaten parallel zu nutzen.
Was sagst du dazu.

Ich wuerde also gerne wissen, in welcher Richtung es weitergehen soll. Wie
ich es am liebsten haette weisst du ja, ich wuerde den rxcache umschreiben
und die alten regexs rauswerfen, und diese pcregexp(E) irgendwie sinnvoll
umbennenen oder evt mit in regexp(E) legen (wenn Arg 1 kein Array ist),
aber das ist dann alles wieder so unuebersichtlich fuer Magier. Weiterhin
hab ich keine Ahnung was der Unterscheid von TEFUN usw ist (nur sehr
grob), was fuer ein Typus es werden soll muesstest du sagen. Das Einbinden
vom Pcre-Paket weiss ich auch nicht wie das geht. Also von Hand schon,
aber wie soll es beim Driver sein? Auch 'extern' builden und dynamisch
linken oder besser den Code mitreinziehen? Aber was ist mit dem configure
des Paketes, da muss ja auch abhaengiger Code sein usw usf... Seufz.

----

Fuer die bislang pcregexp() genannte Funktion wuerde ich uebrigens
regmatch() vorschlagen als Namen, das passt besser in die vorhandenen
reg*() Namen rein - und nach meinen Vorstellungen sollen ja (optional)
alle reg* mit pcre laufen, so ist die Unterscheidung im Funnamen
ueberfluessig.

Start » Magierhandbuch » Todo » f·010406 Letzte Generierung: 06.12.2002, 12:54
Email an: mud@wl.mud.de
Valid HTML 4.01!