13 Stimmen

Compiler für reguläre Ausdrücke

Bei meiner Arbeit habe ich nur wenige Male reguläre Ausdrücke verwenden müssen. In diesen wenigen Fällen habe ich jedoch eine sehr leistungsfähige Ausdrucksform entdeckt, mit der ich einige äußerst nützliche Dinge tun kann.

Das Problem ist, dass die für reguläre Ausdrücke verwendete Sprache falsch ist - Punkt.

Aus psychologischer Sicht ist dies falsch - die Verwendung von körperlosen Symbolen ist nur für Menschen mit einem eidetischen Gedächtnis eine nützliche Referenz. Die syntaktischen Regeln sind zwar klar umrissen, aber nach meiner Erfahrung und dem, was ich von anderen gelernt habe, kann sich die Entwicklung eines erfolgreich funktionierenden regulären Ausdrucks in allen außer den trivialsten Situationen als schwierig erweisen. Dies ist verständlich, da es sich um ein symbolisches Analogon zur Mengenlehre handelt, die eine ziemlich komplizierte Sache ist.

Es kann sich als schwierig erweisen, den Ausdruck, an dem Sie arbeiten, in seine einzelnen Teile aufzulösen. Aufgrund der Beschaffenheit der Sprache ist es möglich, einen regulären Ausdruck auf mehrere Arten zu lesen, wenn man sein primäres Ziel nicht versteht, so dass die Interpretation der Regexes anderer Leute kompliziert ist. In der Lehre von der natürlichen Sprache wird dies als Pragmatik bezeichnet.

Die Frage, die ich stellen möchte, lautet also: Gibt es so etwas wie einen Compiler für reguläre Ausdrücke? Oder kann man überhaupt einen bauen?

Man könnte Regexe, metaphorisch gesehen, als Assembler betrachten - es gibt einige Ähnlichkeiten. Könnte man einen Compiler entwickeln, der eine natürlichere Sprache - eine höhere Sprache - in reguläre Ausdrücke umwandelt? Dann könnte ich in meinem Code meine Regexe unter Verwendung der höheren Sprache in einer Header-Datei definieren und sie bei Bedarf durch eine symbolische Referenz referenzieren. Ich und andere könnten von meinem Code aus auf die Header-Datei verweisen und leichter verstehen, was ich mit meinen Regexes erreichen will.

Ich weiß, dass es von einem logischen Standpunkt aus möglich ist, sonst wären Computer nicht möglich, aber wenn Sie bis hierher gelesen haben, würden Sie dann in Erwägung ziehen, die Zeit zu investieren, um es zu realisieren?

4 Stimmen

Ich finde reguläre Ausdrücke recht einfach zu lesen.

1 Stimmen

Ich denke, die Mehrdeutigkeit einer natürlichen Sprache könnte die Komplikationen eher vergrößern als verringern. Regex scheint anfangs entmutigend zu sein, besonders Dinge wie Backtracking und nicht gierige Operatoren. Nachdem ich kürzlich Regex neu erlernt habe, habe ich einen Abend lang intensiv gelernt, um das meiste zu verstehen. Ich bin mir jedoch sicher, dass jemand mit mehr Erfahrung mich bei Regex leicht übertreffen kann. Wie bei allem, was man wissen sollte, kommt es auf Übung und Ausdauer an.

0 Stimmen

Die Antwort von Andrea Ambu ist eine große Hilfe für alle, die Probleme mit Regex haben. Das ist in etwa das, was ich meinte, aber ich hatte wirklich gehofft, dass es eine Bibliothek mit Makros oder Ähnlichem für verschiedene Programmiersprachen gibt, mit der man eine Textsuche mit einer kombinatorischen Syntax usw. definieren kann. Die Menschen haben unterschiedliche mentale Modelle, und einige Programmierer, mich selbst eingeschlossen, finden es praktisch unmöglich, mit Regex zu arbeiten, obwohl es Drittanbieter gibt, die sie für wenig Geld schreiben. Wenn man regelmäßig damit arbeitet, ist es einfacher, aber wenn es sich nur um ein gelegentliches Projekt handelt, ist es schwierig.

2voto

IAdapter Punkte 58848

Eine Möglichkeit, dieses Problem zu umgehen, ist die Verwendung von Programmen wie QuickREx, das zeigt, wie Regex auf mehreren Testdaten (mit Hervorhebungen) funktioniert. Sie könnten die Textdaten in einer Datei in der Nähe Ihrer Regex speichern und später, wenn Sie sie ändern, verstehen oder korrigieren wollen, wäre das viel einfacher.

1voto

Paul Bruner Punkte 415

Ich sehe viele Antworten, die versuchen, das Problem zu lösen, aber ich glaube, ich habe eine Antwort für Sie.

Ich glaube, die gesamte Regex-Syntax stammt noch aus den späten 70er Jahren. (Ich wünschte, ich könnte irgendeine Art von Geschichte zu diesem Thema finden) Ich habe ein Buch aus dem Jahr 1979 über Buchstabenautomaten in die Hand genommen, und das gesamte Buch ist voll von mathematischen Beweisen für die Suche nach Mustern im Text. Ich werde den Titel besorgen, wenn ich nach Hause komme, und ihn hier aktualisieren.

Die Sache ist die, dass dieses Buch einige sehr komplizierte Symbole in Bezug auf die Infinitesimalrechnung enthielt, die ich nicht verstehen würde, wenn ich nicht einen solchen Kurs absolviert hätte. Ich wette jedoch, dass ein Mathematiker, der diese Syntax regelmäßig verwendet, in der Lage wäre, es wie einen Roman zu lesen.

Es hat einen guten Monat gedauert, bis ich das Lesen regulärer Ausdrücke so weit beherrschte, dass ich nur noch einen Blick darauf werfen muss. Für den Laien sieht es aus wie kompliziertes ASM mit all diesen seltsamen Symbolen darin. Ich betrachte reguläre Ausdrücke nicht als Assembler, sondern als eine mathematische Formel, um Muster im Text zu finden. In Anbetracht der Syntax und der Tatsache, dass sie ursprünglich von Mathematikern stammt, glaube ich nicht, dass es weit hergeholt ist.

Was also einen Compiler betrifft, so bezweifle ich, dass es jemals einen solchen geben wird. Wie dmckee erwähnte: "Ich stelle jedoch fest, dass viele alte Hasen sie nicht zu mögen scheinen." Es gibt Cartoons und Sitcoms, in denen komplizierte mathematische Gleichungen auf Tafeln dargestellt werden. Es ist ein Scherz, um zu zeigen, wie schwer ein bestimmtes Thema ist, aber in Wirklichkeit kann es jeder mit Erfahrung verstehen, wenn man ihm den Subtext und ein wenig Training gibt. Regex ist nicht schwer. Wenn man die Grundlagen einmal verstanden hat, kommt es nur noch auf den verwendeten Parser an. Das ist so, als würden mir einige Kinder sagen, dass sie C/C++ nicht lernen wollen, weil es schwieriger ist als Javascript, obwohl es die gleiche Syntax hat. Es ist eher die Wahrnehmung als die Schwierigkeit.

Sobald Sie Regex gelernt haben, sind es die Motoren, die Ihnen Probleme bereiten. Visual Studio verwendet Klammern anstelle von Klammern für die Gruppierung. Die einfache Regex-Bibliothek SLRE Ich verwende eine einfache Untermenge gegenüber PCRE eine vollständigere Syntax. An diesem Punkt sprechen wir eher von einer neuen Sprache als von einem Werkzeug für den Textabgleich.

Außerdem verwenden die meisten Programmierer eine einzelne kurze Zeile für ihre Regex-Übereinstimmungen, anstatt eine vollständige Regex-Übereinstimmung zu erstellen, weil sie nur einige zufällige Daten analysieren wollen. Regex-Abgleich ist ein Werkzeug wie Bison, yacc oder ANTLR. Ein von Hand erstellter Parser wird immer besser sein, so dass man im Grunde genommen seine eigene Regex kompilieren kann. Warum also die Zeit mit 2 Seiten Code für einen Regex-Abgleich verbringen, wenn eine einfache ansi c while-Schleife schneller ist?

Wenn Sie möchten, dass Regex dynamischer und lesbarer ist, sollten Sie Ihren Parser in der Sprache erstellen, die Sie für Ihr Programm verwenden. Regex ist als Werkzeug gedacht und nicht als vollwertige Sprache.

Nebenbei bemerkt, sehen Sie sich einige der Lua Quellcode zwischen Lua 3.0 und 3.2.2. Sie wechseln von einem Bison-Parser zu einem handgefertigten Parser. Man merkt, wie viel mehr Freiheiten sie damit haben, als wenn sie ein Tool für ihr Text-Parsing verwenden, besonders bei den letzten Funktionsversionen. Natürlich wird es dadurch auch komplizierter, den Code auf dem neuesten Stand zu halten. Es war eine Entscheidung zwischen der Klarheit der *.y-Dateien und der Robustheit der Handarbeit.

1voto

Tino Punkte 8393

Vielleicht können einige JavaScript-Tools helfen:

Leider habe ich noch kein fertiges "Point-and-Click"-JS-Tool gefunden, mit dem sich RegEx einfach erstellen und manipulieren lässt. Die Stärke von RegEx (PCRE, Posix, Python) ist, dass sie

  • sind extrem kompakt (man kann sagen: zu kompakt)
  • kann fast überall verwendet werden
  • immer gleich aussehen (eine ungünstige Größe für alle) und daher im Code leicht zu erkennen sind

Das Rad neu zu erfinden, ist also vielleicht nicht die beste Wahl, und Reguläre Ausdrücke werden intern kompiliert um die Dinge bereits sehr zu beschleunigen. Wenn Sie etwas Ausführlicheres suchen, gibt es LEX y YACC (und ihre Nachfolger), aber meistens übertreiben beide im Vergleich zu der einfachen Art und Weise, wie RegEx angewendet werden kann.

Das Folgende könnte für andere nützlich sein, ist aber nicht Linux, so dass ich es nicht testen konnte:

Wenn Sie weitere gute Links finden, fügen Sie sie vielleicht als Kommentar hinzu. Ich weiß, es ist ein bisschen SO missbräuchlich, darum zu bitten, aber es ist so unglaublich hilfreich. Danke!

0voto

Fionn Punkte 10465

Haben Sie in Erwägung gezogen, einen Parser-Generator (auch bekannt als Compiler-Compiler) zu verwenden, z. B. ANTLR ?

ANTLR hat auch eine Art IDE ( ANTLR arbeitet ), wo Sie Parser visualisieren und debuggen können.

Auf der anderen Seite ist ein Parser-Generator nicht etwas, das man in ein paar Sekunden in eine App einbauen kann, wie eine Regex - und es wäre auch totaler Overkill für etwas wie die Überprüfung des E-Mail-Adressformats.

Auch für einfache Situationen wäre dies völlig übertrieben, und vielleicht ist es besser, einfach Kommentare für Ihre Regex zu schreiben, die erklären, was sie tut.

0voto

Michael Warner Punkte 374

Ich stimme zu, dass die zeilenrauschende Syntax von Regexps ein großes Problem ist, und ehrlich gesagt verstehe ich nicht, warum so viele Leute sie akzeptieren oder verteidigen, denn sie ist für Menschen nicht lesbar.

Was Sie in Ihrem Beitrag nicht erwähnen, was aber fast genauso schlimm ist, ist die Tatsache, dass fast jede Sprache, jeder Editor und jedes Werkzeug seine eigene Variante der Regexp-Syntax hat. Einige von ihnen unterstützen die POSIX-Syntax, wie sie vor vielen Jahren definiert wurde, andere unterstützen die Perl-Syntax, wie sie heute ist. Aber viele haben ihre eigenen, unabhängigen Wege, Dinge auszudrücken, oder welche Zeichen "besonders" sind (Sonderzeichen sind ein anderes Thema) und welche nicht. Was ist escaped und was nicht. Und so weiter. Es ist nicht nur schwierig, eine Regexp zu lesen, die für eine bestimmte Sprache oder ein bestimmtes Tool geschrieben wurde, sondern selbst wenn Sie die Syntaxregeln für Ihre Lieblingsvariante auswendig gelernt haben, können sie Sie in einer anderen Sprache zum Stolpern bringen, wo {2,3} nicht mehr das bedeutet, was Sie erwarten. Das ist wirklich ein Chaos.

Außerdem glaube ich, dass es viele Nicht-Programmierer gibt, die (wenn sie wüssten, dass es sie gibt) es zu schätzen wüssten, wenn sie eine Sprache für die Mustererkennung hätten, die sie in alltäglichen Tools wie Google oder Microsoft Word verwenden könnten. Allerdings müsste es dafür eine einfachere Syntax geben.

Um Ihre Frage zu beantworten: Ich habe schon oft darüber nachgedacht, eine Art plattform-, sprach- und allumfassende Bibliothek zu erstellen, mit der man jede beliebige Regexp-Syntax (sei es Perl oder POSIX oder Emacs usw.) in jede andere Regexp-Syntax "übersetzen" kann. So müssten Sie sich nicht darum kümmern, ob Python-Regexps negatives look-behind können, oder ob Klammern der Zeichenklasse in einem Emacs-Regexp escaped werden sollten. Man könnte sich einfach eine Syntax merken und dann einen Funktionsaufruf machen, um die äquivalente Syntax für das, was man gerade benutzt, herauszuholen.

Von dort aus könnte sie mit einer neuen Sprache für die Mustererkennung erweitert werden, die etwas ausführlicher oder zumindest einprägsamer wäre. Etwas für Leute, die keine Lust haben, eine halbe Stunde damit zu verbringen, einen Regexp zu studieren, um herauszufinden, was er tut. (Und Leute, die Regexps so gut finden, wie sie sind, haben offensichtlich noch nie etwas pflegen müssen, das sie nicht selbst geschrieben haben, sonst würden sie verstehen, dass andere Leute in der Lage sein müssen, das zu analysieren, was sie geschrieben haben.)

Werde ich so ein Tier jemals versuchen? Ich weiß es nicht, es steht schon lange auf meiner To-Do-Liste, und es gibt auch viele einfachere und unterhaltsamere Projekte darauf. Aber wenn Sie etwas Ähnliches in Erwägung ziehen, lassen Sie es mich wissen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X