Wenn Sie nicht wissen, was regulärer Ausdruck (auch bekannt als "regex" oder "regexp") ist, ist es ein unglaublich kraftvolle Sprache für die Ausführung von Suchen und/oder Ersetzen in jeder Art von Text. Regex hat eine lange und ruhmreiche Geschichte (seine Ursprünge reichen bis in die 50er Jahre zurück) und auch heute noch benutzen Sie es täglich ... Sie wissen es vielleicht nur nicht. Regex ist heutzutage in den meisten wichtigen Programmiersprachen und Computersystemen integriert und wird in einer Vielzahl von Anwendungen verwendet.
Regex ist nicht mehr nur etwas für Programmierer: Es taucht heute an allen möglichen Stellen auf. Sie haben sie vielleicht schon beim Abgleich von URLs in Google Analytics, beim Suchen und Ersetzen in Ihrem bevorzugten Texteditor gesehen (einige beliebte Editoren, die Regex unterstützen, sind Erhabenheit, Atom, Wolke9, Notepad++Google Docs und Microsoft Word ... obwohl Word eine Regex-Syntax hat, die sehr Nicht-Standard) und sogar übereinstimmende Dateinamen in unserem großartigen WordPress-Mitgliedschafts-Plugin, MemberPress.
Auch wenn die Regex jetzt an überraschend neuen Stellen auftaucht, wird sie aufgrund ihrer scheinbar kryptischen Natur wohl immer eher von Programmierern und "Power Usern" verwendet werden.
Hier ist also der Punkt in diesem Artikel, an dem Sie sich entscheiden müssen, ob Sie weiterleben wollen, ohne die ungeheure Macht der Regex zu kennen, oder ob Sie die rote Pille schlucken und das Schwert eines Power-Users schwingen wollen! In diesem Beitrag vermittle ich Ihnen die grundlegenden Kenntnisse, die Sie benötigen, um dieses äußerst nützliche Werkzeug für sich arbeiten zu lassen. Fangen wir also an!
Einige Beispiele
Wie sehen Regex-Anweisungen aus? Wenn Sie eine Regex-Anweisung sehen würden, ohne zu wissen, was sie ist, würde sie wie ein völliges Kauderwelsch aussehen.
Hier ist ein Beispiel für eine Regexp-Anweisung zum Abgleich mit einer Telefonnummer:
\(?\d{3}\)?[- ]\d{3}-\d{4}
Hier ist eine, die mit einer URL übereinstimmt:
https?:\/\/[\w-]+(\.[\w-]{2,})*(:\d{1,5})?
Und eine, die mit einer E-Mail-Adresse übereinstimmen kann:
[\w\d._%+-]+@[\w\d.-]+\.[\w]{2,4}
Schließlich gibt es noch eine einfache Such- und Ersetzungsfunktion, die alle Domänennamen mit der Subdomäne "test" findet und in eine Subdomäne "www" ändert:
Suche: test\.([^\.]+)\.com
Ersetzen: www.$1.com
Schon eingeschüchtert? Das muss nicht sein. Ich werde erläutern, wie Regex-Anweisungen interpretiert werden, was wir in jeder dieser Anweisungen tun und wie Sie Ihre eigenen erstellen können.
Wie man Regex liest
Reguläre Ausdrücke sind wie normale Suchanweisungen, aber auf Steroiden. Wenn Sie beispielsweise den Namen "Harry" auf einer Webseite suchen, klicken Sie auf control-f und geben "Harry" ein, um ihn zu finden. Mit Regex können Sie mehr tun, als nur nach "Harry" zu suchen. Sie könnten nach "Harry" oder "Bob" suchen mit (Harry|Bob)
oder Sie können nach jedem Wort, das mit "Ha" beginnt, suchen mit Ha\S*
.
Für Ihren Computer wird Text als eine "Zeichenkette" von Zeichen dargestellt. Wenn Sie schon einmal gehört haben, wie Programmierer über Code sprechen, haben Sie wahrscheinlich den Begriff "String" gehört, wenn sie sich auf eine Variable beziehen.
Reguläre Ausdrücke werden von links nach rechts gelesen (genau wie im Englischen und vielen anderen Sprachen) und erklären dem Computer, worauf er beim Scannen einer Zeichenfolge von links nach rechts achten muss. Wenn der Computer die einzelnen Zeichen betrachtet, folgt er diesem Ablauf:
Wenn Sie sich dieses Flussdiagramm ansehen, werden Sie, so kompliziert es auch erscheinen mag, etwas sehr Vertrautes erkennen. Es ist so ziemlich identisch mit dem, was Sie erwarten würden jede Suche auf einem Computer und wie Suchen, mit denen Sie derzeit vertraut sind, bereits ablaufen. Regex fügt der normalen Suche lediglich einige extrem leistungsstarke Funktionen hinzu.
Die Grundlagen
Bevor wir nun damit beginnen, unsere obigen Regex-Beispielanweisungen zu zerlegen, sollten wir einige der grundlegenden Befehlszeichen von Regex durchgehen:
Wiederholer: *, + und {...}
Das Sternchen (*) und das Pluszeichen (+) sind Wiederholungszeichen. Ein Wiederholungszeichen wird nur nach einem anderen Zeichen oder einer eingeschlossenen Anweisung verwendet und weist den Computer an, das vorangehende Zeichen X-mal zu wiederholen. Das Sternchen entspricht dem vorangehenden Zeichen 0 bis unendlich oft, das Pluszeichen 1 bis unendlich oft; {2}
wird es genau 2 Mal treffen; {4,6}
wird zwischen 4 und 6 Mal genau übereinstimmen; und {7,}
wird es zwischen 7 und unendlich oft wiederholen.
Platzhalter: .
Sie sind wahrscheinlich daran gewöhnt, dass das Sternsymbol als Platzhalter verwendet wird, aber in Regex ist es ein Punkt (.). Der Punkt wird einfach mit jede Charakter.
Fakultativ: ?
Wie der Wiederholer wird auch das optionale Zeichen, ein Fragezeichen (?), nur nach einem anderen Zeichen oder einer eingeschlossenen Anweisung verwendet. Wenn es vorhanden ist, teilt es dem Computer mit, dass das vorangehende Zeichen in den Suchergebnissen vorhanden sein kann oder nicht.
Anfang und Ende der Zeichenfolge: ^ und $
Wenn das Caret (^) am Anfang der Regex verwendet wird, zeigt es an, dass der erste Teil der Zeichenkette abgeglichen werden soll. Das Dollarzeichen ($) am Ende der Regex bedeutet, dass das Ende der Zeichenkette gefunden werden soll.
Mögliche Charaktere: [...]
Die in Klammern eingeschlossenen Zeichen geben die Zeichen an, die an dieser Stelle übereinstimmen könnten. Wenn Sie zum Beispiel ein 'n', 'm', 'l' oder '_' abgleichen wollen, können Sie Ihrer Regex Folgendes hinzufügen [nml_]
. Wenn Sie nur einen Buchstaben oder eine Zahl zuordnen möchten, können Sie Folgendes hinzufügen [A-Za-z0-9]
.
Wenn Sie ein beliebiges Zeichen abgleichen wollen außer der möglichen Zeichen können Sie einfach ein Caret (^) hinter die öffnende Klammer setzen. Wenn Sie zum Beispiel jedes Zeichen außer 'x', 'y', 'z' oder '_' abgleichen wollen, können Sie dies mit der Anweisung tun: [^xyz_]
. Wie Sie sehen, können Sie auf diese Weise feinkörnig steuern, was Sie auf einer Zeichen-für-Zeichen-Basis abgleichen.
Beiliegende Erklärungen: (...)
Manchmal möchten Sie Abschnitte Ihrer Regex als Block verwenden oder sie für später speichern. Dazu brauchen Sie die Anweisung nur in Klammern einzuschließen.
Die Flucht: \
Was ist nun, wenn Sie nach den tatsächlichen Zeichen "+", "." usw. suchen wollen? Nun, wenn Sie einen Backslash davor setzen, dann sagt das Ihrem Computer, dass Sie versuchen, ein tatsächliches Suchzeichen zu finden, und es nicht als Befehlszeichen interpretieren sollen.
Kurzschrift-Zeichen: /s, /S, /d, /D, /w, /W und /b
Diese Zeichen sind sehr nützlich und helfen Ihnen, bestimmte Zeichengruppen zu finden. Hier ist, wie sie sich aufteilen:
/s
passt auf alle Leerzeichen wie Leerzeichen und Tabulator/S
passt auf alle Zeichen ohne Leerzeichen/d
passt auf jedes beliebige Ziffernzeichen/D
passt auf alle nicht-ziffrigen Zeichen/w
entspricht einem beliebigen Wortzeichen (grundsätzlich alphanumerisch)/W
passt auf jedes Nicht-Wort-Zeichen/b
passt auf jede Wortgrenze (dazu gehören Leerzeichen, Bindestriche, Kommas, Semikolons usw.)
Natürlich gibt es noch viele andere, mächtigere Dinge, die Sie mit Regex tun können, aber mit diesen Grundlagen erhalten Sie die Werkzeuge, die Sie für 90% Ihrer fortgeschrittenen Suchanforderungen benötigen.
Aufschlüsselung unserer Telefonnummer Beispiel
Okay, jetzt, wo Sie die Werkzeuge haben, lassen Sie uns unsere Beispiele durchgehen, um zu sehen, wie sie funktionieren, beginnend mit unserer Übereinstimmung für die Telefonnummer:
\(?\d{3}\)?[- ]\d{3}-\d{4}
Wir werden es also nach Aussagen aufschlüsseln:
\(?
Dies ist die erste Anweisung, nach der der Computer suchen wird. Sie beginnt mit einem Escape-Zeichen (\), gefolgt von einer offenen Klammer ((), gefolgt von einem optionalen Zeichen (?). Dies weist die Regex an, nach einer offenen Klammer zu suchen, um den Beginn einer Telefonnummer zu signalisieren, aber dass diese nicht in jedem Fall einer Telefonnummer vorhanden sein muss.
\d{3}
Die zweite Anweisung beginnt mit dem Abkürzungszeichen für Ziffer (\d) und enthält dann eine Wiederholung ({3}), die 3 Ziffern erfordert. Sie endet nicht mit einem Fragezeichen, weil diese drei Ziffern nicht optional sind - sie müssen vorhanden sein, damit das Suchergebnis als Telefonnummer gilt.
\)?
Jetzt prüft der Computer, ob eine optionale schließende Klammer vorhanden ist, aber wenn diese nicht vorhanden ist, kann der Text trotzdem übereinstimmen.
[- ]
Danach folgt eine Anweisung für mögliche Zeichen, die entweder ein Leerzeichen oder einen Bindestrich als Übereinstimmung sucht.
\d{3}-\d{4}
Schließlich gibt es noch einige Anweisungen, die 3 Ziffern gefolgt von einem Bindestrich und dann 4 Ziffern erwarten.
Sie können dies hier in Aktion sehen und ausprobieren: http://regex101.com/r/nW9iC5/3
Ein paar Dinge, die Ihnen an dieser Regex auffallen könnten, ist, dass sie nur mit zwei akzeptablen Formaten für Telefonnummern übereinstimmen wird:
(888) 888-8888
888-888-8888
Es passt nicht zu einer Vielzahl von inakzeptablen Telefonnummernformaten wie z. B.:
8888888888
88-8888-8888
Aber es wird auch mit einigen Formaten übereinstimmen, die möglicherweise nicht geeignet sind:
(888-888-8888
888) 888-8888
(888)-888-8888
Was könnte man Ihrer Meinung nach tun, um sicherzustellen, dass diese Regex nur mit den entsprechenden Formaten übereinstimmt?
Aufschlüsselung unserer URL-Regex
Zunächst möchte ich darauf hinweisen, dass die folgende Regex keineswegs eine umfassende URL-Matching-Regex ist. Sie stimmt nur mit einer Webadresse ohne Argumente überein und hat einige andere Probleme, würde aber dazu dienen, viele URLs effektiv abzugleichen.
https?:\/\/[\w-]+(\.[\w-]+)*(:\d{1,5})?
Und nun zur Aufschlüsselung:
https?:\/\/
Diese erste Anweisung stimmt mit dem Protokoll der URL überein. Da das "s" ein Fragezeichen nach sich hat, ist es optional. Außerdem stehen Escape-Zeichen vor den Schrägstrichen, was normalerweise in Regex passieren muss, um Schrägstriche abzugleichen. Es gibt also eigentlich nur zwei Möglichkeiten, wie eine URL mit dieser Anweisung übereinstimmen könnte, nämlich mit http://
oder https://
.
[\w-]+
Hier haben wir eine Anweisung mit möglichen Zeichen, gefolgt von einem Pluszeichen. Das bedeutet, dass die nächsten Zeichen 1 oder mehr Wortzeichen oder Bindestriche sein müssen.
(\.[\w-]+)*
Hier haben wir die Anweisung, die einem Punkt gefolgt von Wortzeichen oder Bindestrichen entspricht. Die gesamte Anweisung ist in Klammern eingeschlossen und wird von einem Pluszeichen gefolgt, das dem Computer mitteilt, dass wir die gesamte Sequenz null oder mehr Mal wiederholen können. Dieser Abschnitt könnte also übereinstimmen mit .memberpress
oder .memberpress.com
oder .memberpress.de
, und so weiter.
(:\d{1,5})?
Schließlich sieht diese Anweisung vor, dass am Ende der URL eine optionale Portnummer angehängt wird, die aus einem Doppelpunkt, gefolgt von 1 bis 5 Ziffern, besteht, die dann in Klammern gesetzt und von einem Fragezeichen gefolgt werden, um die gesamte Anweisung optional zu machen.
Hier können Sie ein wenig damit herumspielen: http://regex101.com/r/vL5uZ2/2
Diese Regex wird übereinstimmen:
- https://memberpress.com
- https://memberpress.com
- http://localhost:3000
ABER es werden keine Parameter gefunden, die einer URL wie dieser folgen:
- http://localhost:3000?test=1&page=5
Was könnten Sie zu dieser Regex hinzufügen, um einige Parameter am Ende einer URL zu finden?
Wenn Sie an der umfassendsten URL-Matching-Regex interessiert sind (eine, die Parameter, Unicode-Zeichen, große TLDs usw. findet) es gibt viele von ihnen die Sie sich ansehen können, aber anscheinend ist die von Diego Perini erstellte Version die umfassendste und genaueste. können Sie sich auf seinem Github gist ansehen.
Aufschlüsselung unserer E-Mail-Regex
Eine weitere häufige Verwendung von Regex ist der Abgleich von E-Mail-Adressen. Unser Regex zum Abgleich von E-Mail-Adressen passt auf eine große Anzahl von E-Mail-Adressen:
[\w\d\._%+-]+@[\w\d.-]+\.[\w]{2,4}
Hier ist die Aufschlüsselung:
[\w\d\._%+-]+
Diese Anweisung passt auf ein oder mehrere Wortzeichen, Ziffern, Punkte, Unterstriche, Prozentzeichen, Pluszeichen oder Bindestriche.
@
Jede E-Mail-Adresse braucht ein "@"-Symbol, und das passt natürlich zu dieser.
[\w\d.-]+
Nach dem '@'-Symbol müssen wir mit dem Domänennamen beginnen. Diese Anweisung wird mit einem oder mehreren Wortzeichen, Ziffern, Punkten oder Bindestrichen übereinstimmen.
\.[\w]{2,4}
Jetzt müssen wir die Top-Level-Domain abgleichen, die aus einem Punkt, gefolgt von 2 bis 4 Wortzeichen, besteht.
Sie können auch hier mit dieser Regex herumspielen: http://regex101.com/r/yQ2wP9/1
Obwohl diese Regex nicht 100% umfassend ist, sollte sie die meisten Adressen abdecken können.
Regex Suchen und Ersetzen
In vielen Fällen geht es also nicht nur um den Abgleich von Mustern in Ihrem Text mit Regex, sondern auch um die Nutzung der Möglichkeiten von Suchen und Ersetzen mit Regex.
Nehmen wir das Beispiel des Suchens und Ersetzens von oben:
Suche: test\.([^\.]+)\.com
Ersetzen: www.$1.com
Hier ist die Aufschlüsselung, beginnend mit dem Suchmuster:
test\.
Dieser erste Teil passt auf jeden Teil der Zeichenkette, der mit "test" beginnt.
([^\.]+)
Diese Anweisung passt auf ein oder mehrere Zeichen, die alles außer einem Punkt sind. Die gesamte Anweisung ist aus einem anderen Grund als bisher in Klammern eingeschlossen: Diesmal geht es darum, das, was durch diese Anweisung gefunden wird, für die Ersetzung zu speichern.
\.com
Schließlich muss er mit einem ".com" am Ende übereinstimmen.
In der Ersetzung können wir nun "$1" verwenden, um das einzuschließen, was wir im Suchmuster zwischen den Klammern gespeichert haben. Wenn Sie eine zweite Anweisung wie diese im Suchmuster hatten, können Sie sie in der Ersetzung verwenden, indem Sie "$2" verwenden.
Sie können mit dieser Such- und Ersetzungsregex hier herumspielen: http://regex101.com/r/bW5vX8/1
Dieses Suchmuster hat jedoch einige echte Einschränkungen. Es kann nur URLs finden, die mit "test." beginnen und mit ".com" enden. Wie könnte man es so abändern, dass es auch mit URLs übereinstimmt, die auf ".com", ".net" oder ".org" enden?
Mehr über Regex lernen
Diese Einführung hat Ihnen einen Crashkurs über reguläre Ausdrücke gegeben, aber es gibt noch viel mehr zu lernen. Mehr Informationen über Regex finden Sie unter Wikipedia oder reguläre-ausdrücke.info.
Hey Blair, das Einzige, was ich an deinen Beiträgen mag, ist die Einzigartigkeit der Themen. Heutzutage liest man immer und immer wieder das Gleiche... all diese umgeschriebenen Artikel, von denen niemand weiß, wie oft sie geschrieben wurden. Ich lese jeden einzelnen Beitrag von Ihnen, weil Sie zwei Dinge einsetzen, die nicht viele Vermarkter einsetzen - Fachwissen und Professionalität. Vielen Dank für die interessanten Beiträge und bitte machen Sie weiter so. Wir alle brauchen Menschen wie Sie 🙂
Danke Ivo ...
Ich habe ein Problem mit Formularen, die den Benutzer auf ein bestimmtes Format für die Telefonnummer festlegen. Mir ist aufgefallen, dass in vielen Kontaktformularen, in denen Unternehmen technische Dienstleistungen für internationale Benutzer anbieten, eine Telefonnummer erforderlich ist. Außerhalb der USA können die Telefonnummern jedoch unterschiedliche Formate haben.
Zum Beispiel:
+45 8765-4321
+43 1-123-456-7890
+46 987-654-321
In vielen Fällen wird der Benutzer gezwungen, eine gefälschte Nummer anzugeben, um das Formular auszufüllen. Nehmen wir das erste Beispiel; es passt zufällig in das typische Zwangsformat vieler Online-Formulare. Die Person, die das Formular liest, wird jedoch glauben, dass die Nummer nach Oregon und nicht nach Dänemark geht. Man sollte meinen, dass Unternehmen, die für sich selbst international werben, sich dessen bewusst sind. Wie würden Sie dies handhaben?
Laurence, danke für den Kommentar ... Sie sprechen einen guten Punkt an. In diesem Artikel ist mein regulärer Ausdruck ziemlich starr und an US-Telefonnummern gebunden. Aber das Tolle an Regex ist, dass man es so locker oder starr machen kann, wie man es will. Wenn ich zum Beispiel nur ganze Zahlen, Leerzeichen und Bindestriche mit einem Pluszeichen vergleichen wollte, könnte ich dies tun:
Diese Regex würde auf jedes Ihrer obigen Beispiele passen, ist aber sehr großzügig. Sie würde auch auf unsinnige Muster wie:
+– — — —- —
+4-9-1-2-0-1-3-0-2
600-001-001-005-3838-38-28383
Möglicherweise wäre es besser, überhaupt keine Bindestriche, Leerzeichen oder Klammern in der Zahl zuzulassen, wenn Sie internationale Formate unterstützen wollen. Ein Beispiel hierfür wäre:
Das würde mit allen Ihren Zahlen ohne Bindestriche übereinstimmen:
+4587654321
+4311234567890
+46987654321
Diese Lösung wäre großartig, ist aber auch extrem liberal ... Sie hätten keine Möglichkeit, den Ländercode oder Ähnliches zu überprüfen.
Eine andere mögliche Lösung, wenn Sie wissen, welche Länder Sie ansprechen, wäre, alle möglichen Formate, die Sie unterstützen möchten, in Ihrer Regex wie folgt zu behandeln:
Dieses Muster würde auf jedes Ihrer drei obigen Beispiele zutreffen, aber nicht auf US-Telefonnummern usw. Es bietet eine bessere Validierung als die obigen Regex-Anweisungen, da es starrer ist, aber es wird auch keine Nummern validieren, die nicht Teil der Ländercodes 45, 43 und 46 sind.
Wenn Sie ein wenig googeln, finden Sie vielleicht eine Master-Regex für die Validierung von Telefonnummern aus der ganzen Welt. Ich habe noch keine gefunden ... wenn Sie also eine finden, lassen Sie es mich wissen. Alternativ könnten Sie Ihre eigene umfassende Regex dafür schreiben (ich bin mir sicher, dass sie sehr beliebt wäre) ... Sie müssten nur eine Technik verwenden, wie ich sie in der letzten Regex hier verwendet habe ... die aber alle numerischen Formate aus aller Welt umfasst. Ein guter Anfang wäre ein Blick auf diese Seite auf wikipedia.
Auf jeden Fall hoffe ich, dass das hilft ... Ich weiß, dass es kein Patentrezept ist, aber hoffentlich kann es Ihnen zumindest einen Hinweis auf die richtige Richtung geben.
Ich danke Ihnen für diesen informativen und dringend benötigten Artikel. Ich finde, dass die Regex-Kodierung von Leuten, die sie kennen, oft als selbstverständlich angesehen wird, und dass sie normalerweise erwarten, dass alle anderen sie auch kennen. Jetzt habe ich eine verständliche Quelle, auf die ich mich beziehen kann.
Ich verstehe, dass die Kontrolle, ob die eingegebenen Ziffern einem vorgegebenen Standard entsprechen, eine Funktion ist, mit der Fehler minimiert werden sollen. Was internationale Telefonnummern in einem Formularfeld anbelangt, so vermute ich, dass es einfacher ist, darauf zu vertrauen, dass der Benutzer überprüft, ob er die richtige Telefonnummer eingegeben hat, als zu versuchen, das Feld auf die vielen Möglichkeiten hin zu überprüfen. Die wichtigste Anwendung von regex war für mich übrigens bisher die .htaccess-Datei.
Ich schätze es, dass Sie nicht nur auf Kommentare in Ihrem Blog antworten, sondern dass Ihre Antworten gut durchdacht und sinnvoll sind. Großartige Arbeit.
Danke Laurence.
Großes Argument ... aber das ist ein Teil der Schönheit von Regex. Ich meine, Sie müssen es gar nicht verwenden ... aber wie ich in meiner ersten Antwort sagte, könnten Sie eine extrem leichtgewichtige Regex machen, die nur erzwingt, dass sie Ziffern und Bindestriche oder so eingeben.
Ja, die Verwendung von Regex mit der RedirectMatch-Direktive ist extrem nützlich ... sie macht es so einfach, URL-Strukturen zuzuordnen. Es ist besonders wichtig, dies zu verwenden, wenn Sie eine Website migrieren, bei der sich die Links alle ändern werden ... Ich meine, wenn Sie keine Art von URL-Zuordnung wie RedirectMatch verwenden, kann Ihr SEO bei der Migration Ihrer Website dramatisch leiden.
Blair,
Vielen Dank für diesen Beitrag! Ich vermeide immer reguläre Ausdrücke, weil ich mir nie die Zeit genommen habe, die Syntax zu verstehen. Dies bricht es wirklich nach unten und macht es einfach.
Ich habe keine Angst mehr vor regulären Ausdrücken 🙂
Großartig, Jamie! Ich bin froh, dass ich helfen konnte!