Bei der Erforschung regulärer Ausdrücke (auch als RegEx-es bekannt) gibt es viele Personen, die reguläre Ausdrücke als den Heiligen Gral zu betrachten scheinen. Etwas, das so kompliziert aussieht - muss nur die Antwort auf jede Frage sein. Sie neigen dazu zu glauben, dass jedes Problem mit regulären Ausdrücken lösbar ist.
Andererseits gibt es auch viele Menschen, die versuchen, reguläre Ausdrücke um jeden Preis zu vermeiden. Sie versuchen, einen Weg um reguläre Ausdrücke zu finden und zusätzliche Codierung zu akzeptieren, auch wenn reguläre Ausdrücke eine kompaktere Lösung wären.
Warum werden reguläre Ausdrücke als so kontrovers angesehen? Gibt es weit verbreitete Missverständnisse darüber, wie sie funktionieren? Oder könnte es eine breite Überzeugung sein, dass reguläre Ausdrücke im Allgemeinen langsam sind?
Antworten:
Ich glaube nicht, dass Leute gegen reguläre Ausdrücke protestieren, weil sie langsam sind, sondern weil sie schwer zu lesen und zu schreiben sind und es schwierig ist, sie richtig zu machen. Während es einige Situationen gibt, in denen reguläre Ausdrücke eine effektive, kompakte Lösung für das Problem darstellen, werden sie manchmal in Situationen eingebettet, in denen es besser ist, stattdessen einen einfach zu lesenden, wartbaren Codeabschnitt zu verwenden.
quelle
|
oder.*
) ungeeignet , da sie eine Stack-Maschine und Backtracking verwenden. Aus diesem Grund müssen Sie Ihre regulären Ausdrücke in Perl, Java, Python, Ruby… sorgfältig optimieren.grep
Zum Beispiel kompilieren Engines für reguläre Ausdrücke im alten Stil ( z. B.) zuerst das Muster zu einem DFA. Danach ist die Komplexität des Musters weitgehend irrelevant. Ich habe gerade Java und grep für den gleichen Text und das gleiche Muster verwendet: 22min vs 2s. Hier ist die Wissenschaft: swtch.com/~rsc/regexp/regexp1.htmlRegexes wartbar machen
Ein wichtiger Fortschritt bei der Entmystifizierung der Muster, die zuvor als „reguläre Ausdrücke“ bezeichnet wurden, ist Perls
/x
Regex-Flag, das manchmal(?x)
beim Einbetten geschrieben wird und Leerzeichen (Zeilenumbruch, Einrücken) und Kommentare zulässt. Dies verbessert die Lesbarkeit und damit die Wartbarkeit erheblich. Der Leerraum ermöglicht kognitives Chunking, sodass Sie sehen können, welche Gruppen mit welchen Gruppen verbunden sind.Moderne Muster unterstützen jetzt auch relativ nummerierte und benannte Rückreferenzen. Das bedeutet, dass Sie keine Erfassungsgruppen mehr zählen müssen, um herauszufinden, ob Sie
$4
oder benötigen\7
. Dies hilft beim Erstellen von Mustern, die in weitere Muster aufgenommen werden können.Hier ist ein Beispiel für eine relativ nummerierte Erfassungsgruppe:
Und hier ist ein Beispiel für den überlegenen Ansatz benannter Captures:
Grammatische Regexe
Das Beste ist , dass diese benannten Captures in einem
(?(DEFINE)...)
Block platziert werden können, sodass Sie die Deklaration von der Ausführung einzelner benannter Elemente Ihrer Muster trennen können. Dadurch verhalten sie sich eher wie Unterprogramme innerhalb des Musters.Ein gutes Beispiel für diese Art von „grammatikalischem Regex“ finden Sie in dieser und dieser Antwort . Diese sehen viel eher wie eine grammatikalische Erklärung aus.
Wie letzterer Sie erinnert:
Dies kann nicht überbetont werden. Wenn Sie diese Dinge nicht in Ihren Mustern verwenden, werden Sie natürlich oft einen Albtraum schaffen. Aber wenn Sie sie verwenden, brauchen Sie nicht.
Hier ist ein weiteres Beispiel für ein modernes grammatikalisches Muster, das zum Parsen von RFC 5322 verwendet wird: use 5.10.0;
Ist das nicht bemerkenswert - und großartig? Sie können eine Grammatik im BNF-Stil direkt in Code übersetzen, ohne ihre grundlegende Struktur zu verlieren!
Wenn Ihnen moderne grammatikalische Muster immer noch nicht ausreichen, bietet das brillante
Regexp::Grammars
Modul von Damian Conway eine noch sauberere Syntax mit überlegenem Debugging. Hier ist derselbe Code zum Parsen der Neufassung von RFC 5322 in ein Muster aus diesem Modul:Es gibt viele gute Dinge auf der Perlre- Manpage , aber diese dramatischen Verbesserungen der grundlegenden Regex- Designfunktionen sind keineswegs nur auf Perl beschränkt. In der Tat ist die Manpage zu pcrepattern möglicherweise leichter zu lesen und deckt dasselbe Gebiet ab.
Moderne Muster haben fast nichts mit den primitiven Dingen zu tun, die Ihnen in Ihrer Klasse für endliche Automaten beigebracht wurden.
quelle
/x
. Es ist die grammatikalische Verwendung der Regexes mit(?&name)
internen Regex-Subroutinen, die dies wirklich zum Leuchten bringt.re.VERBOSE
Flagge.Regexes sind ein großartiges Werkzeug, aber die Leute denken: "Hey, was für ein großartiges Werkzeug, ich werde es verwenden, um X zu machen!" Dabei ist X etwas, für das ein anderes Tool besser ist (normalerweise ein Parser). Es ist der Standard mit einem Hammer, bei dem Sie ein Problem mit dem Schraubendreher benötigen.
quelle
split($pattern,$string)
vsexplode($delimiter,$string)
- zum Glück wird das erstere abgeschrieben, aber viele Codes verwendeten das erstere, wenn sie nur die Leistung des späteren benötigten. Einverstanden, RegEx bieten ein einfaches Werkzeug, um einige Dinge zu tun, aber wenn Sie nicht die volle Kraft der regulären Ausdrücke benötigen, sieFast jeder, den ich kenne, der regelmäßig reguläre Ausdrücke verwendet (Wortspiel beabsichtigt), hat einen Unix-Hintergrund, in dem er Tools verwendet, die REs als erstklassige Programmierkonstrukte wie grep, sed, awk und Perl behandeln. Da es fast keinen syntaktischen Aufwand gibt, einen regulären Ausdruck zu verwenden, steigt ihre Produktivität, wenn sie dies tun.
Im Gegensatz dazu neigen Programmierer, die Sprachen verwenden, in denen REs eine externe Bibliothek sind, dazu, nicht zu berücksichtigen, was reguläre Ausdrücke auf den Tisch bringen können. Die "Zeitkosten" des Programmierers sind so hoch, dass entweder a) REs nie als Teil ihrer Ausbildung erschienen sind oder b) sie nicht in REs "denken" und lieber auf bekanntere Muster zurückgreifen.
quelle
Mit regulären Ausdrücken können Sie eine benutzerdefinierte Finite-State-Machine (FSM) auf kompakte Weise schreiben, um eine Eingabezeichenfolge zu verarbeiten. Es gibt mindestens zwei Gründe, warum die Verwendung regulärer Ausdrücke schwierig ist:
Die Softwareentwicklung der alten Schule erfordert viel Planung, Papiermodelle und sorgfältige Überlegungen. Reguläre Ausdrücke passen sehr gut in dieses Modell, denn um einen effektiven Ausdruck richtig zu schreiben, muss man viel darauf starren und die Pfade des FSM visualisieren.
Moderne Softwareentwickler würden viel lieber Code ausarbeiten und einen Debugger verwenden, um die Ausführung zu durchlaufen und festzustellen, ob der Code korrekt ist. Reguläre Ausdrücke unterstützen diesen Arbeitsstil nicht sehr gut. Ein "Lauf" eines regulären Ausdrucks ist effektiv eine atomare Operation. Es ist schwierig, die schrittweise Ausführung in einem Debugger zu beobachten.
Es ist zu einfach, einen regulären Ausdruck zu schreiben, der versehentlich mehr Eingaben akzeptiert, als Sie beabsichtigen. Der Wert eines regulären Ausdrucks stimmt nicht wirklich mit gültigen Eingaben überein, sondern mit ungültigen Eingaben . Techniken, um "negative Tests" für reguläre Ausdrücke durchzuführen, sind nicht sehr fortgeschritten oder zumindest nicht weit verbreitet.
Dies führt dazu, dass reguläre Ausdrücke schwer zu lesen sind. Wenn Sie nur einen regulären Ausdruck betrachten, ist viel Konzentration erforderlich, um alle möglichen Eingaben zu visualisieren, die abgelehnt werden sollten, aber fälschlicherweise akzeptiert werden. Haben Sie jemals versucht, den regulären Ausdruckscode eines anderen zu debuggen ?
Wenn es heute bei Softwareentwicklern einen Widerstand gegen die Verwendung regulärer Ausdrücke gibt, liegt dies meiner Meinung nach hauptsächlich an diesen beiden Faktoren.
quelle
Die Leute neigen dazu, reguläre Ausdrücke für schwierig zu halten. aber das liegt daran, dass sie sie falsch verwenden. Schreiben komplexer Einzeiler ohne Kommentare, Einrückungen oder benannte Captures. (Sie stopfen Ihren komplexen SQL-Ausdruck nicht in einer Zeile ohne Kommentare, Einrückungen oder Aliase, oder?) Also ja, für viele Leute machen sie keinen Sinn.
Wenn Ihr Job jedoch etwas mit dem Parsen von Text zu tun hat (ungefähr jede Webanwendung da draußen ...) und Sie keinen regulären Ausdruck kennen, saugen Sie an Ihrem Job und verschwenden Ihre eigene Zeit und die Ihrer Arbeitgeber. Es gibt ausgezeichnete Ressourcen , die Ihnen alles über sie beibringen, was Sie jemals wissen müssen, und vieles mehr.
quelle
x
Modifikator für reguläre Ausdrücke, der bewirkt, dass Leerzeichen ignoriert werden. Auf diese Weise können Sie den regulären Ausdruck in einige Zeilen einfügen und Kommentare hinzufügen.re.X
akare.VERBOSE
.x
Modifikator in tcl. Ich glaube, es ist ziemlich Standard, da tcl im Gegensatz zu anderen Sprachen kein PCRE verwendet.Weil ihnen das beliebteste Lernwerkzeug in den allgemein akzeptierten IDEs fehlt: Es gibt keinen Regex-Assistenten. Nicht einmal Autocompletion. Sie müssen das Ganze ganz alleine codieren.
quelle
()
, quadratischen[]
oder geschweiften{}
Klammern initiiert . Es wird auch aus dem Backslash heraus funktionieren." Reguläre Ausdrücke: Jetzt haben Sie zwei Probleme " ist ein großartiger Artikel von Jeff Atwood zu diesem Thema. Grundsätzlich sind reguläre Ausdrücke "schwer"! Sie können neue Probleme verursachen. Sie sind jedoch wirksam.
quelle
Ich denke nicht, dass sie so kontrovers sind.
Ich denke auch, dass Sie Ihre eigene Frage irgendwie beantwortet haben, weil Sie darauf hinweisen, wie dumm es wäre, sie überall zu verwenden ( nicht alles ist eine reguläre Sprache 2 ) oder sie überhaupt nicht zu verwenden. Sie als Programmierer müssen eine intelligente Entscheidung treffen, wann reguläre Ausdrücke dem Code helfen oder ihn verletzen. Bei einer solchen Entscheidung sind zwei wichtige Dinge zu beachten: Wartbarkeit (was Lesbarkeit impliziert) und Erweiterbarkeit.
Für diejenigen, die ihnen besonders abgeneigt sind, ist meine Vermutung, dass sie nie gelernt haben, sie richtig zu benutzen. Ich denke, die meisten Leute, die nur ein paar Stunden mit einem anständigen Tutorial verbringen, werden sie herausfinden und sehr schnell fließend werden. Hier ist mein Vorschlag, wo ich anfangen soll:
http://docs.python.org/howto/regex
Obwohl diese Seite über reguläre Ausdrücke im Kontext von Python spricht, habe ich festgestellt, dass die Informationen an anderer Stelle sehr zutreffend sind. Es gibt einige Dinge, die Python-spezifisch sind, aber ich glaube, sie sind klar vermerkt und leicht zu merken.
quelle
Reguläre Ausdrücke sind Zeichenfolgen, was arithmetische Operatoren für Zahlen sind, und ich würde sie nicht als kontrovers betrachten. Ich denke, dass selbst ein ziemlich millitanter OO- Aktivist wie ich (der dazu neigt, andere Objekte gegenüber Strings zu wählen) es schwer haben würde, sie abzulehnen.
quelle
Das Problem ist, dass Regexe möglicherweise so mächtig sind, dass Sie Dinge damit tun können, für die Sie etwas anderes verwenden sollten.
Ein guter Programmierer sollte wissen, wo er sie verwenden soll und wo nicht. Das typische Beispiel ist das Parsen nicht regulärer Sprachen (siehe Entscheiden, ob eine Sprache regulär ist ).
Ich denke, dass Sie nichts falsch machen können, wenn Sie sich zunächst auf echte reguläre Ausdrücke beschränken (keine Erweiterungen). Einige Erweiterungen können Ihr Leben ein bisschen einfacher machen, aber wenn Sie etwas finden, das schwer als echte Regex auszudrücken ist , kann dies ein Hinweis darauf sein, dass eine Regex nicht das richtige Werkzeug ist.
quelle
Sie können fast genauso gut fragen, warum Goto umstritten sind.
Wenn Sie so viel "offensichtliche" Macht erhalten, neigen die Leute dazu, sie für Situationen zu missbrauchen, für die sie nicht die beste Option sind. Die Anzahl der Personen, die beispielsweise CSVs oder XML oder HTML in regulären Ausdrücken analysieren möchten, überrascht mich. Es ist das falsche Werkzeug für den Job. Einige Benutzer bestehen jedoch trotzdem darauf, reguläre Ausdrücke zu verwenden.
Persönlich versuche ich, dieses glückliche Medium zu finden - verwende Regexe für das, wofür sie gut sind, und vermeide sie, wenn sie nicht optimal sind.
Beachten Sie, dass Regexe weiterhin zum Parsen von CSVs, XML, HTML usw. verwendet werden können. In der Regel jedoch nicht in einer einzelnen Regex.
quelle
Ich denke nicht, dass "kontrovers" das richtige Wort ist.
Aber ich habe unzählige Beispiele gesehen, in denen Leute sagen: "Was ist der reguläre Ausdruck, den ich brauche, um so und so eine String-Manipulation durchzuführen?" Welches sind XY Probleme.
Mit anderen Worten, sie sind von der Annahme ausgegangen, dass eine Regex das ist, was sie brauchen, aber sie wären besser dran mit einem split (), einer Übersetzung wie perls tr ///, bei der die Zeichen durch die anderen ersetzt werden, oder nur ein Index ().
quelle
Dies ist ein interessantes Thema.
Viele Regexp- Liebhaber scheinen die Prägnanz der Formel mit Effizienz zu verwechseln.
Darüber hinaus erzeugt ein regulärer Ausdruck, der viel Nachdenken erfordert, für den Autor eine massive Befriedigung, die ihn sofort legitimiert.
Aber ... reguläre Ausdrücke sind so praktisch, wenn die Leistung kein Problem darstellt und Sie schnell mit einer Textausgabe umgehen müssen, beispielsweise in Perl. Auch während der Leistung ist ein Problem kann man es vorziehen , nicht zu versuchen , die regexp - Bibliothek zu schlagen , indem einen selbstgemachten Algorithmus, fehlerhaft sein kann oder weniger effizient.
Daneben gibt es eine Reihe von Gründen, aus denen Regexps beispielsweise zu Unrecht kritisiert werden
quelle
Was ich denke ist, dass das Lernen von Regex und das Aufrechterhalten von Regex unpopulär ist. Die meisten Entwickler sind faul oder die meisten verlassen sich auf externe Bibliotheken, um die Analyse für sie durchzuführen. Sie verlassen sich auf Google, um die Antwort zu erhalten, und fragen sogar in Foren nach der vollständige Code für ihr Problem. Aber wenn es darum geht, einen regulären Ausdruck zu implementieren oder zu ändern / zu pflegen, schlagen sie einfach fehl.
Es gibt ein beliebtes Sprichwort: "Freunde lassen Freunde Regex nicht zum Parsen von HTML verwenden."
Aber was mich betrifft, habe ich mit Regex vollständige HTML-Parser erstellt, und ich finde, dass Regex HTML-Zeichenfolgen sowohl in Bezug auf die Geschwindigkeit als auch in Bezug auf den Speicher besser analysieren kann (wenn Sie eine Idee haben, was Sie erreichen sollen :)).
quelle
Reguläre Ausdrücke sind für viele Menschen, auch für mich, ein ernstes Rätsel. Es funktioniert großartig, aber es ist wie das Betrachten einer mathematischen Gleichung. Ich freue mich, Ihnen mitteilen zu können, dass jemand unter http://regexlib.com/ endlich einen konsolidierten Speicherort für verschiedene Funktionen für reguläre Ausdrücke erstellt hat . Wenn Microsoft jetzt nur eine Klasse für reguläre Ausdrücke erstellen würde, die automatisch einen Großteil der gängigen Aufgaben wie das Entfernen von Buchstaben oder das Filtern von Datumsangaben erledigt.
quelle
Ich finde reguläre Ausdrücke manchmal von unschätzbarem Wert. Wenn ich einige "unscharfe" Suchen durchführen muss und diese möglicherweise ersetzen muss. Wenn Daten variieren können und eine gewisse Zufälligkeit haben. Wenn ich jedoch einfach suchen und ersetzen oder nach einer Zeichenfolge suchen muss, verwende ich keine regulären Ausdrücke. Obwohl ich viele Leute kenne, die das tun, benutzen sie es für alles. Das ist die Kontroverse.
Wenn Sie einen Stift in die Wand stecken möchten, verwenden Sie keinen Hammer. Ja, es wird funktionieren, aber wenn Sie den Hammer bekommen, könnte ich 20 Reißnägel in die Wand stecken.
Reguläre Ausdrücke sollten für das verwendet werden, wofür sie entwickelt wurden, und nicht weniger.
quelle
Während ich denke, dass Regexes ein wesentliches Werkzeug sind, ist das Ärgerlichste an ihnen, dass es verschiedene Implementierungen gibt. Geringe Unterschiede in der Syntax, den Modifikatoren und insbesondere in der "Gier" können die Dinge wirklich chaotisch machen, was Versuch und Irrtum erfordert und manchmal rätselhafte Fehler erzeugt.
quelle
In einigen Fällen denke ich, dass Sie sie verwenden müssen. Zum Beispiel, um einen Lexer zu bauen.
Meiner Meinung nach ist dies eine Sichtweise von Menschen, die Regexp schreiben können, und von Menschen, die dies nicht (oder kaum) tun. Ich persönlich denke, dies ist ein guter Gedanke, um beispielsweise die Eingabe eines Formulars zu überprüfen, sei es in Javascript, um den Benutzer zu warnen, oder in serverseitiger Sprache.
quelle
Ich denke, es ist eine weniger bekannte Technik unter Programmierern. Es gibt also keine breite Akzeptanz dafür. Und wenn Sie einen nicht-technischen Manager haben, der Ihren Code oder Ihre Arbeit überprüft, ist ein regulärer Ausdruck sehr schlecht. Sie werden Stunden damit verbringen, einen perfekten regulären Ausdruck zu schreiben, und Sie werden einige Punkte für das Modul erhalten, wenn Sie glauben, dass er / sie so wenige Codezeilen geschrieben hat. Wie bereits an anderer Stelle erwähnt, ist das Lesen regulärer Ausdrücke eine sehr schwierige Aufgabe.
quelle
Anständige Systeme für reguläre Ausdrücke, wie sie in Lex und Yacc für die Compilerdefinition verwendet werden, sind gut, sehr nützlich und sauber. In diesen Systemen werden Ausdruckstypen in Bezug auf andere definiert. Es sind die abscheulichen, missgebildeten, unlesbaren, einzeiligen regulären Ausdrücke mit Zeilenrauschen, die häufig in Perl- und Sed-Code (usw.) vorkommen und „umstritten“ sind (Müll).
quelle
Die beste gültige und normale Verwendung für Regex ist die Validierung des E-Mail-Adressformats.
Das ist eine gute Anwendung davon.
Ich habe unzählige Male reguläre Ausdrücke als Unikate in TextPad verwendet, um flache Dateien zu massieren, CSV-Dateien zu erstellen, SQL-Einfügeanweisungen zu erstellen und dergleichen.
Gut geschriebene reguläre Ausdrücke sollten nicht zu langsam sein. Normalerweise sind die Alternativen, wie z. B. Tonnen von Anrufen zum Ersetzen, weitaus langsamere Optionen. Könnte es auch in einem Durchgang tun.
Viele Situationen erfordern genau reguläre Ausdrücke und sonst nichts.
Das Ersetzen von nicht druckbaren Sonderzeichen durch harmlose Zeichen ist eine weitere gute Verwendung.
Ich kann mir natürlich vorstellen, dass es einige Codebasen gibt, die reguläre Ausdrücke zum Nachteil der Wartbarkeit überbeanspruchen. Das habe ich selbst noch nie gesehen. Ich wurde tatsächlich von Code-Reviewern gemieden, weil ich nicht genug reguläre Ausdrücke verwendet habe.
quelle