Die eBA und reguläre Ausdrücke

Samstag, 25. Dezember 2021

Günter Jürgensmeier hat sich die eBA genauer angeschaut (PDF) und fällt ein vernichtendes Urteil:

Die eBA ist mit Sicherheit die schlechteste Implementierung eines für Literatur gedachten Suchsystems in der uns bekannten Welt.

Nun ist die eBA sicherlich nicht perfekt und die von Jürgensmeier angeführten Kritikpunkte sind durchaus valide – allein: Seine Schlussfolgerung, das System sei irreparabel und »kaputt by design« scheint mir dann doch etwas übertrieben. Ich habe zu wenig Hintergrundwissen, um das wirklich beurteilen zu können, habe aber so meine Zweifel, ob das Problem des »unüberwindbaren Seitenwechsels« wirklich so unüberwindbar ist. Aber es mag jeder selbst entscheiden, ob er oder sie Jürgensmeier in seinem harschen Urteil folgt oder nicht. Darum soll es hier auch gar nicht gehen.

Die Kritik an der eBA ist mir nur ein willkommener Anlass, kurz auf den Einsatz von »regulären Ausdrücken«, wie sie die eBA bietet, einzugehen. Diese werden auf der Website nur erwähnt und an zwei, drei Beispielen demonstriert. Da mag eine kurze Erläuterung vielleicht ganz hilfreich sein. Vorausgeschickt sei aber, dass ich zum einen in Sachen RegEx kein Experte bin, zum anderen die eBA mir da mitunter etwas erratisch zu reagieren scheint. Aber sei’s drum.

Reguläre Ausdrücke

Reguläre Ausdrücke (auch als Regular Expressions oder kurz RegEx bekannt) sind formalisierte Zeichenketten, die Muster definieren, nach denen Zeichenmengen (Texte) durchsucht werden können. Reguläre Ausdrücke sind sehr mächtig, tendieren aber auch dazu, praktisch unlesbar zu werden. Allerdings scheint die eBA den Sprachumfang von RegEx nur rudimentär implementiert zu haben.

Ein regulärer Ausdruck – also das Zeichenmuster, nach dem gesucht werden soll – steht üblicherweise (und auch in der eBA) in Schrägstrichen: /Ausdruck/. Ein Punkt . innerhalb eines regulären Ausdrucks steht als Platzhalter für genau ein (beliebiges) Zeichen. Mit exakt:/.osen/ wird etwa »Hosen«, »Rosen«, »Dosen«, »kosen«, »tosen« etc. gefunden. Das entspricht der Standardsuche mit Fragezeichen: exakt:?osen. (Das exakt: gehört nicht zum regulären Ausdruck, sondern ist eine Besonderheit der eBA, mit der die standardmäßig aktive unscharfe Suche ausgeschaltet wird.)

Quantifier

Mit den »Quantifiern« lässt sich angeben, wie oft ein Ausdruck oder Zeichen auftauchen muss, um gefunden zu werden. Der Quantifier bezieht sich dabei immer auf das direkt links neben ihm stehende Zeichen bzw. auf eine Zeichengruppe (Gruppen werden übrigens in () notiert). Dabei steht das Pluszeichen + für »mindestens einmal« (auch mehrfach), das Sternchen * für »beliebig oft« (auch gar nicht). Mit exakt:/.+osen/ findet man also nicht nur »Rosen« oder »Hosen« sondern etwa auch »geländerlosen« oder »wertlosen«. Das entspricht in der Standardsuche exakt:*osen.

Das Beispiel /essa.+/ auf der Website findet alle Zeichenketten, die »essa« gefolgt von mindestens einem oder mehr beliebigen Zeichen enthalten: »Essay«, »Essays«, »Essayist«, »EssaySchätze« etc. Das gleiche Ergebnis liefert allerdings auch die Standardsuche mit essa*.

Zwei Dinge sind hier übrigens bemerkenswert und unterscheiden die eBA vom Standard-RegEx:

  • Es wird nicht zwischen Groß- und Kleinschreibung unterschieden. Bei einer RegEx sind normalerweise /essay/ und /Essay/ zwei verschiedene Zeichenketten.
  • Gesucht wird ab Wortanfang (»interessant« wird z.B. nicht gefunden). Möchte man nur ab Wortanfang suchen, muss man das in einer RegEx üblicherweise mit \b markieren.

Möchte man alle Begriffe finden, in denen die Buchstabenfolge »essa« auftaucht, muss man das in der eBA so notieren: /.+essa.+/. Hier gibt es zudem eine kleine Diskrepanz zur Standardsuche, bei der der Suchbegriff *essa* lauten würde. Die findet 1060 Ergebnisse, die RegEx nur 1055. Ergänzt man den Suchbegriff zu exakt:*essa*, werden auch in der Standardsuche 1055 Ergebnisse ausgewiesen.

Üblicherweise lässt sich in einer RegEx auch die genaue Anzahl festlegen, in dem man sie in {min,max} setzt, wobei min angibt, wie oft ein Zeichen oder ein Ausdruck mindestens vorkommen muss, max legt entsprechend die Obergrenze fest. Mit exakt:/n{2,5}/ müssten alle Wörter mit »nn«, »nnn«, »nnnn« und »nnnn« gefunden werden. Das funktioniert so aber nicht mit der eBA.

Hier hilft es, Anfang und Ende der gesuchten Zeichenkette um beliebige Zeichen zu erweitern: exakt:/.*n{2,5}.*/ (= beliebig viele beliebige Zeichen, gefolgt von mindestens zwei, aber maxmial fünf »n«, gefolgt von beliebig vielen beliebigen Zeichen). Spielt die Obergrenze keine Rolle, kann man dies auch anders notieren: exakt:/.*nnn+.*/ (= beliebig viele beliebige Zeichen, gefolgt von »nn«, gefolgt von mindestens einem weiteren »n«, gefolgt von beliebig vielen beliebigen Zeichen).

Klassen

Interessant ist die Möglichkeit, Klassen zu definieren. Dazu führt man in [] alle gewünschten Zeichen auf. Mit exakt:/[HDR]osen/ werden »Hosen«, »Dosen« und »Rosen« gefunden, nicht aber »tosen« oder »losen«. Ein ^ zu Beginn einer Klasse negiert die gesamte Klasse: exakt:/[^HDR]osen/ findet die Wörter mit »osen«, die nicht mit einem »H«, »D« oder »R« beginnen, etwa »tosen«, »losen«, »Posen« oder »Kosen«. Mit dem auf der Website angeführten Beispiel exakt:/be[iy]fall.+/ werden entsprechend alle Vorkommnisse von »Beifall« (wie gesagt: Groß-/Kleinschreibung wird ignoriert) bzw. »Beyfall« gefolgt von mindestens einem Zeichen gefunden.

Ein Beispiel für eine Klasse, bei dem sich die Entwickler der eBA ein wenig von den Möglichkeiten haben mitreißen lassen, das aber niemand in der Praxis tatsächlich einsetzen würde, ist das hier exakt:/[,.!?%&\/-;:›‹„”…‘()„»«]*Und ich noch dabei[,.!?%&\/-;:›‹„”…‘()„»«]*/. Das schaut wüster aus, als es ist.

In der Klasse werden sämtliche Satzzeichen angeführt (das scheint mir doppelt zu sein), wobei der Schrägstrich / durch einen Backslash \ entwertet wird, weil er ansonsten als Ende des regulären Ausdrucks erkannt würde. Anschließend sorgt ein * dafür, dass sämtliche aufgeführten Zeichen mehrfach (oder gar nicht) in beliebiger Reihenfolge auftauchen dürfen. Diese Bedingung wird am Schluss wiederholt und umschließt so die Phrase, um die es eigentlich geht: Und ich noch dabei. Das funktioniert, geht aber sehr viel einfacher: exakt:/.*Und ich noch dabei.*/. Damit wird der Ausdruck zwar auf beliebige Zeichen vor und nach der Phrase geändert – aber für das Wiederfinden des Zitats spielt das ja keine Rolle. Um so einen Zeichenwust, wie ihn die eBA da als Beispiel bringt, zu vermeiden, sind in RegEx übrigens Zeichenklassen vordefiniert. Um alles zu maskieren, was kein Wortzeichen ist – also keine Ziffer, kein Buchstabe und kein Unterstrich _ – wird normalerweise \W geschrieben, aber diese vordefinierten Klassen werden von der eBA nicht unterstützt.

Es ist auch möglich, ganze Bereiche zu bestimmen, etwa alle Buchstaben ([a-z], Groß-/Kleinschreibung wird wieder ignoriert) oder alle Ziffern ([0-9]). Möchte man etwa wissen, wieviele zehnstellige Zahlen bei Schmidt auftauchen, dann führt dieser Ausdruck zum Ziel: exakt:/[0-9]{10}/. Wer, aus welchen Gründen auch immer, wissen möchte, auf welche Wörter mit 20 Buchstaben ein Komma, ein Punkt oder ein Semikolon folgt, kann das so ermitteln: exakt:/[a-z]{20}[.,;]+/. – Zu Klassen fallen mir keine Alternativen in der Standardsuche ein ;-).

* * *

Damit sind die Möglichkeiten der regulären Ausdrücke bei weitem nicht erschöpft (hier wurde allenfalls an der Oberfläche gekratzt), aber zum einen führt das hier entschieden zu weit (über den Einsatz von RegEx sind ganze Bücher geschrieben worden), zum anderen hat die eBA ohnehin nur eine beschränkte Auswahl zu bieten. Ob noch mehr geht als hier kurz dargestellt, weiß ich nicht (Dinge wie die in RegEx ebenfalls mögliche Umgebungssuche habe ich nicht ausprobiert). Aber vielleicht helfen ja schon diese knappen Erläuterungen, dass so manches Zitat besser gefunden wird.