[Allegro] Vb.196 Preprint: Regulaere Ausdruecke
Bernhard Eversberg
ev at biblio.tu-bs.de
Mo Dez 18 10:06:27 CET 2006
Verlautbarung 196 der Entw.Abt. 2007-01-03
-------------------------------
VORABDRUCK!
Noch unvollstaendig!
Neue Funktionen erst mit V27.0 im Jan.2007 verfuegbar
=================
Regulaere Ausdruecke (engl. "regular expressions")
--------------------
Dieses Konzept ist jedem Programmierer bekannt, vor allem in den
Skriptsprachen Perl und Python, und in der UNIX-Welt ganz allgemein.
Weiter unten steht kurz beschrieben, wie solche Ausdruecke aussehen.
Im allegro-System wird die Verwendung von regulaeren Ausdruecken vor
allem fuer die Volltextsuche gewuenscht, aber auch allgemein als ein
maechtigeres Werkzeug zum Durchsuchen von Zeichenfolgen, das ueber
einen schlichten Byte-fuer-Byte-Vergleich hinausgeht.
Mit V27.0 wird schon ein neuer FLEX zur Volltextsuche bereitgestellt
werden, der schneller ist als der bisherige und der mit regulaeren
Ausdruecken arbeiten kann.
Hinweis fuer Kenner
Man verwendet ueblicherweise frei verfuegbare Unterprogramme, die man
im Netz leicht finden kann, auch fuer C++. Fuer "allegro" wurde die
kompakte Implementierung von Ozan S. Yigit gewaehlt:
http://www.cse.yorku.ca/~oz/regex.bun
Die Versionen von Perl und Python sind z.B. noch maechtiger, aber nicht
alles, was dort moeglich ist, waere im allegro-Kontext brauchbar.
Ein paar Modifikationen waren noetig, um den Besonderheiten von
allegro-Daten gerecht zu werden.
Neuer FLEX-Befehl srx - die Grundlage
-------------------------------------
srx <suchausdruck>
sucht in der iV nach dem <suchausdruck>, wobei dies ein
sog. "regulaerer Ausdruck" sein kann, im einfachen Fall ein
schlichtes Wort.
Mit if yes stellt man fest, dass der Ausdruck in der iV vorkommt.
Wenn hinter srx nichts steht, wird als Suchwort nicht der Inhalt
der iV benutzt (denn diese soll ja durchsucht werden!), sondern
die Variable #u!! . Man wuerde deshalb schreiben
var ...suchbegriff...
ins #u!!
var ... zu durchsuchender Text...
srx
if can mes;end // formaler Fehler im Suchbegriff!
Dieses scheinbar umstaendliche Verfahren wurde gewaehlt, weil
man damit die hoechstmoegliche Flexibilitaet in der Anwendung hat.
Durchsucht wird also jeweils der Text in der iV. Deren maximale
Laenge ist 256K.
Beispiel: Feststellen, ob in der Textdatei abc.txt das Wort
"ViewListe" vorkommt. Dafuer genuegen 4 Zeilen:
// zuerst den Suchbegriff in die Variable #u!! setzen
#u!! viewliste
var Fabc.txt // Text der Datei abc.txt in die iV einlesen
srx // darin suchen nach Inhalt von #u!!
if yes mes gefunden!
Komplette Anwendung
-------------------
Der neue FLEX ftr.flx leistet eine Volltextsuche in der gesamten
Datenbank. Darin kann man das Verfahren studieren.
Tip: Wenn ein Suchbegriff mehrfach (u.U. sehr oft) zur Anwendung
kommt, kann man ihn vorher formal pruefen, damit das "if can"
nicht bei jeder Anwendung auszufuehren ist. Das geht so:
var "abcd"
srx
if cancel mes;end
Mit "mes" wird dann die Fehlermeldung angezeigt. In Regulaeren
Ausdruecken kann man jede Menge formale Fehler machen ...
ftr.flx nutzt einen weiteren neuen Befehl:
fetch r
Dieser holt einen ganzen Datensatz aus der Datendatei in die iV.
Er wird weiter unten genauer beschrieben.
Und so formuliert man regulaere Ausdruecke
------------------------------------------
Ein Ausdruck dieser Art muss bei der Anwendung in #u!! stehen, der
zu durchsuchende Text in der internen Variablen.
Die Punkte 2 und 3 sind allegro-spezifisch modifiziert, 1 gibt es
im gaengigen Standard nicht.
1. Unterstrich an erster Position: Exaktheit
_abc oder abc
Exakte bzw. umcodierte Suche
Setzt man einen _ vor den Suchbegriff, wird dieser exakt gesucht,
d.h. mit Eingabe von _Müll findet man nur Müll, nicht Muell oder
muell oder müll.
Ohne _ wird der Datentext umcodiert, der Suchbegriff aber
nicht! Man muss also muell eingeben, um Müll, Muell und
muell und müll mit einer einzigen Suche zu finden.
Man wird meistens umcodiert suchen wollen, deshalb fordert diese
Variante kein Steuerzeichen. Wichtig: Dann nur Kleinbuchstaben
ohne Akzente eingeben, Umlaute aufgeloest, ss statt ß!
(Der _ hat nur in der ersten Position diese Wirkung.)
Zur Umcodierung werden die p- oder q-Befehle in den Indexparametern
verwendet, es wird aber noch weitere Alternativen geben.
2. Zirkonflex auf erster Position: Feldanfang
^abc findet abc nur, wenn es an einem Feldanfang steht.
Dabei gilt der Anfang des Feldtextes, ohne die Kategorienummer.
Also: _^Shakesp findet #40 Shakespeare und #31 Shakespeare
Wenn der zu durchsuchende Text (der iV-Inhalt) nicht mit '#'
beginnt, gilt das erste Zeichen als Textanfang.
3. Dollar an letzter Position: Feldende
abc$ findet abc nur, wenn es am Ende eines Feldes steht.
Wenn der zu durchsuchende Text (der iV-Inhalt) nicht mit '#'
beginnt, gilt nur das Ende des gesamten Textes.
4. Punkt ist Joker (engl. "wildcard")
AB.D findet jedes ABxD, mit beliebigem Zeichen x
Mehrere Punkte innerhalb eines Suchbegriffs moeglich, jeder Punkt
steht dann fuer genau ein Zeichen.
5. Stern: Mehrfachvorkommnis
ABc*D findet ABD, ABcD, ABccD, ABcccD ... (d.h. c darf fehlen)
6. Punkt-Stern: Binnentrunkierung (Kombination aus 4 und 5)
AB.*CD findet ABxyzCD mit beliebiger Folge xyz, aber im selben
Datenfeld, nicht irgendwo weiter hinten im Datensatz!
Das entspricht AB,CD im Programm SRCH
7. Plus: wie Stern, aber mindestens ein Vorkommnis
ABx+D findet ABxD, ABxxD, ... (d.h. mind. ein x muss vorkommen)
8. Eckige Klammern: Variantensuche
AB[pq]Z findet ABpZ und ABqZ
AB[c-f]Z findet ABcZ, ABdZ, ABez, ABfZ
Die Angabe [c-f] deutet also an, dass eines der Zeichen im
Bereich c-f an der Stelle vorkommen muss.
[^c-f] bedeutet Negation, d.h. Zeichen c-f sollen an der Stelle
nicht auftreten
Eine Angabe [c-fp-y] verlangt, dass ein Zeichen aus dem Bereich
c-f oder p-y vorkommt.
9. Kombinationen [...]* und [...]+
* und + koennen auch hinter ] auftreten und beziehen sich dann auf
die in [...] angegebenen Zeichen, d.h.
AB[c-f]*XY findet z.B. ABXY, ABcXY, ABdXY, ABceXY, ABcdcdfXY, etc
AB[c-f]+XY findet aber ABXY nicht, nur die anderen wie bei *
Beispiele: ele[ck]tri findet electri und elektri
theat[er]+ findet Theater und theatre
i[sz]abel+a findet Isabella, Izabella und Izabela
10. Steuerzeichen suchen
AB\xCD findet ABxCD
Das Zeichen x soll vorkommen. Man setzt \ vor solche Zeichen,
die sonst eine Steuerfunktion haben, also [ ] + * $ ^ _
11. \< : Wortanfang suchen
\<abc findet abc, aber nur wenn es an einem Wortanfang steht.
Ein "Wort" beginnt mit Buchstabe oder Ziffer, d.h. es geht
irgendein anderes Zeichen oder kein Zeichen voran, z.B. auch -
12. \> : Wortende suchen
abc\> findet abc, aber nur wenn es an einem Wortende steht.
Hinter c soll also im Text ein Sonderzeichen oder nichts folgen.
10 und 11 sind kombinierbar
13. \(...\) : Wiederholung eines Ausdrucks
\(AB\)xyz\1 findet ABxyzAB
\(AB\).*\1 findet AB...AB
mit beliebiger Zeichenfolge zwischen den beiden AB.
Es koennen weitere Ausdruecke \(...\) auftreten, die danach mit \2,
\3 etc. im selben Gesamtausdruck wiederholt werden koennen.
Neue FLEX-Befehlsoption: fetch r
---------------------------------
Damit holt man aus einer geoeffneten allegro-Datendatei einen
kompletten Datensatz in die iV, wobei die Felder dann durch
LF # getrennt sind (das sind die Codes 10 und 35)
Das hat zur Folge, dass man mit nachfolgendem insert den
ganzen Datensatz an den Arbeitsspeicher uebergeben kann.
Wenn fetch r gegeben wird, muss zu dem Zeitpunkt aber der
Lesezeiger in der Datei auf dem ersten Zeichen des naechsten
Satzes stehen, normalerweise also auf der 0 von #00 (in den
Dateien sind die # nicht mitgespeichert).
Das stellt man sicher, indem man direkt vorher gibt
fetch b // erstes Byte holen
fetch b4 // Satznummer holen
Der zweite Befehl entfaellt, wenn man eine Grunddatei (Typ .ALG)
vor sich hat. Nach dem fetch r steht der Lesezeiger genau auf
dem Steuerbyte des nächsten Satzes (Code 1, 8 oder 9).
Mehr Informationen über die Mailingliste Allegro