PHP und reguläre Ausdrücke: die Grundlagen für Anfänger

In Erwartung des Starts eines neuen Threads zum Kurs „Backend-Entwickler in PHP“ sowie des zugehörigen Kurses „Framework Laravel“ möchten wir den von unserem freiberuflichen Autor erstellten Artikel teilen.

Achtung! Dieser Artikel ist für das Kursprogramm nicht relevant und nur für Anfänger nützlich. Für vertiefende Kenntnisse laden wir Sie zu einem kostenlosen zweitägigen Online-Intensivkurs zum Thema "Erstellen eines Telegramm-Bot für die Bestellung von Kaffee in der Einrichtung und Online-Zahlung" ein. Der zweite intensive Tag wird hier stattfinden.




Hallo allerseits! Alle mit dem kommenden [20]{2,}0 Jahr. Heute möchte ich auf ein Thema eingehen, das manchmal ein Witzthema ist: "Warum müssen Sie all das lernen, wenn Sie bereits vorgefertigte Lösungen haben?" Bis "Können Sie auch ganz Perl lernen?" Mit der Zeit beginnen jedoch viele Programmierer, reguläre Ausdrücke zu beherrschen, und auf Habré gibt es keinen einzigen neuen Artikel zu diesem Thema ( obwohl sich reguläre Ausdrücke in letzter Zeit nicht allzu sehr geändert haben ). Es ist Zeit, einen anderen zu schreiben!


Reguläre Ausdrücke, die von ihrer spezifischen Implementierung isoliert sind


Reguläre Ausdrücke (auf Englisch als RegEx oder als Regex bezeichnet ) sind ein Werkzeug, das für verschiedene Optionen zum Studieren und Verarbeiten von Text verwendet wird: Suchen, Prüfen, Suchen und Ersetzen eines Elements aus Buchstaben oder Zahlen (oder anderen Zeichen in einschließlich Sonderzeichen und Satzzeichen). Anfänglich kamen reguläre Ausdrücke aus dem Umfeld der wissenschaftlichen Forschung, die in den 50er Jahren auf dem Gebiet der Mathematik durchgeführt wurde, in die Welt der Programmierung.

Jahrzehnte später wurden die Prinzipien und Ideen in die UNIX-Betriebssystemumgebung übertragen (insbesondere in das Dienstprogramm grep ) und in die Perl-Programmiersprache implementiert, die zu Beginn des Internets im Backend weit verbreitet war (und bis heute für eine solche Aufgabe verwendet wird, aber bereits weniger) wie Formularvalidierung.



Wenn sie einfach zu sein scheinen, warum sind sie dann auf den ersten Blick so beängstigend?

Tatsächlich kann jeder Ausdruck „regulär“ sein und zur Überprüfung oder Suche nach beliebigen Zeichen verwendet werden. Zum Beispiel können die Wörter Pavel oder example@mail.ru auch als reguläre Wörter verwendet werden, allerdings nur in einem ziemlich engen Schlüssel. Um die Leistung regulärer Ausdrücke in der PHP-Umgebung zu testen, ohne den Server oder das Hosting zu starten, können Sie den folgenden Onlinedienst verwenden (die Verarbeitung russischer Zeichen funktionierte einfach nicht). Für den Anfang verwenden wir nur Pavel als regulären Ausdruck.

Angenommen, wir haben den folgenden Text:

Pavel weiß zu viel. Pavel benutzt Nginx und ist kein Wanderer.

Nun haben reguläre Ausdrücke beide Vorkommen des Wortes Pavel gefunden. Es ist großartig, aber es hört sich nicht sehr nützlich an (es sei denn, Sie versuchen aus irgendeinem Grund, so etwas wie das Ausmaß der Erwähnung des Wortes Sir in Krieg und Frieden durch Vim und Python zu analysieren, aber dann habe ich keine Fragen an Sie).

Ausdrucksvariabilität

Wenn Ihr regulärer Ausdruck variabel ist (z. B. kennen Sie nur einen Teil davon und müssen die Anzahl der Vorkommen von Jahren zwischen 2000 und 2099 ermitteln), können Sie den folgenden regulären Ausdruck verwenden: 20 ..

Text: Junge Schriftsteller schreiben viele Dinge. Beispielsweise unterscheidet sich ein 2002 geborener Schriftsteller stark von 2008 und 2012.

Hier können wir mit Hilfe von regulären Ausdrücken alle Jahre finden, aber bisher macht dies keinen Sinn. Höchstwahrscheinlich brauchen wir keine Jahre nach 2012 (obwohl junge Schriftsteller unter 8 Jahren beleidigt sein können, aber darüber jetzt nicht). Es lohnt sich, sich mit Zeichensätzen zu befassen, aber dazu später mehr, da wir uns jetzt mit einem weiteren wichtigen Teil regulärer Ausdrücke befassen: der Flucht vor Metazeichen.

Stellen Sie sich vor, wir müssen die Anzahl der Vorkommen von Dateien mit der Erweiterung .doc (nehmen wir an, wir exportieren nur bestimmte Dateien, die in unsere Datenbank hochgeladen wurden). Aber bedeutet ein Punkt einfach ein beliebiges Zeichen? Also, was ist zu tun?
Hier hilft uns die Flucht vor Metazeichen mit einem Backslash. Jetzt ist der Ausdruck \.doc erfolgreich genug, um nach Text mit der Erweiterung .doc zu suchen:

Regulärer Ausdruck: \.doc

Text: kursach .doc , nepodozritelneyfail.exe , work .doc , shaprgalka.rtf doc

Wie Sie sehen, können wir die Anzahl der Dateien mit der Erweiterung .doc in der Liste erfolgreich finden. Mit diesem regulären Ausdruck können wir jedoch nicht die vollständigen Dateinamen in ein Array ziehen. Es ist Zeit, einen Blick auf die Zeichensätze zu werfen.

Finde eine ganze Reihe von Charakteren

In regulären Ausdrücken wird für die Zuordnung zu einer Menge Metazeichen verwendet - eckige Klammern [ ] . Es können zwei beliebige ASII-Zeichen als Anfang und Ende eines Bereichs angegeben werden. Nehmen wir für eine einfache Implementierung an, wir möchten alle nummerierten Dateien von 0 bis 9 mit der Erweiterung .jpg .

Regulärer Ausdruck: [0-9]\.jpg

Text: 1.jpg , 2.jpg , 3.jpg , photo.jpg, anime.jpg, 8.jpg , jkl.jpg

Es ist zu beachten, dass der Dateiname mit mehr als 1 Ziffern nicht von unserem regulären Ausdruck abgedeckt wird. Etwa Multiple Choice wird etwas geringer ausfallen, aber stellen Sie sich vorerst vor, wir müssten plötzlich das gegenteilige Ergebnis erzielen. Fügen Sie das Metazeichen ^ (das im Gegensatz dazu in regulären Ausdrücken bis zu zwei Funktionen hat). Um es als Ausnahme zu verwenden, müssen Sie es genau unserem Set hinzufügen:

Regulärer Ausdruck: [^0-9]\.jpg

Text: 1.jpg, 2.jpg, 3.jpg, phot o.jpg , anim e.jpg , 8.jpg, jk l.jpg

Aber ohne Mehrfachauswahl sind dies natürlich minderwertige Ausdrücke.

Nützliche Tabellen

Hier ist eine Tabelle mit Metazeichen:

\Entkomme dem Metazeichen als reguläres Zeichen
^Suche nach einem bestimmten Zeichen am Anfang der Zeile (aber nur, wenn Sie es aus der Menge ausschließen [])
$Zeilenende
|Alternative
()Gruppierung
\ walle alphanumerischen Zeichen (aus irgendeinem Grund stimmen viele Handbücher nicht mit digitalen Zeichen überein)
\ WGleiches, genau das Gegenteil
\ sBeliebiges Leerzeichen
\ SBeliebiges NICHT-Leerzeichen


Leerraum-Metazeichentabelle
[\ b]Rückgabe eines einzelnen Zeichens
\ fSeitenübersetzung
\ nZeilenvorschub
\ rWagenrücklauf
\ tTabellierung
\ vvertikale Registerkarte


Multiple Choice: Einfache Validierung


Mit dem erworbenen Wissen werden wir versuchen, einen regulären Ausdruck zu erstellen, der beispielsweise Wörter mit weniger als drei Buchstaben findet (eine Standardaufgabe für die Spam-Abwehr). Wenn wir versuchen, den folgenden regulären Ausdruck zu verwenden - \w{1,3} (in dem das Metazeichen \w beliebiges Zeichen angibt und geschweifte Klammern die Anzahl der Zeichen von wieviel bis wieviel angeben), werden wir alle Zeichen in einer Reihe hervorheben Wortanfang und Wortende im Text, dazu benötigen wir das Metazeichen \b .

Regulärer Ausdruck: \b\w{1,3}\b:

Text: gutes Wort
nicht
Ei

Nicht schlecht! Jetzt können Wörter, die kürzer als drei Buchstaben sind, nicht in unsere Datenbank aufgenommen werden. Schauen wir uns die Validierung der Postanschrift an:

Regulärer Ausdruck: \w+@\w+\.\w+

Anforderungen: In der E-Mail am Anfang sollte ein beliebiges Zeichen stehen (Zahlen oder Buchstaben, da E-Mail, die am Anfang nur aus Zahlen besteht, durchaus üblich ist). Dann kommt das @ -Symbol, dann so viele Zeichen, wie Sie möchten, gefolgt von einem maskierten Punkt (d. H. Nur einem Punkt) und einer Domäne der ersten Ebene.

Betrachten Sie die Zeichenwiederholung genauer.

Schauen wir uns nun genauer an, wie Zeichen in regulären Ausdrücken wiederholt werden. Sie möchten zum Beispiel eine beliebige Kombination von Zahlen von 2 bis 6 im Text finden:

Regulärer Ausdruck: [2-6]+

Text: Hier kommen 89 verschiedene 234 Ziffern 24 .

Lassen Sie mich Ihnen eine Tabelle aller Metazeichenquantifizierer geben:

*Zeichen wiederholen 0 und unendlich
+von 1 bis unendlich wiederholt
{n}genau n mal wiederholen
{n,}von n bis unendlich
{n1, n2}von n1 bis n2 mal genau
?0 oder 1 Zeichen, nicht mehr


Die Anwendung von Quantifizierern ist nicht kompliziert. Abgesehen von einer Einschränkung: gierige und faule Quantifizierer. Hier ist die Tabelle:

**?
++?
{n,}{n,}?


Lazy Quantifiers unterscheiden sich von Greedy darin, dass sie die minimale und nicht die maximale Anzahl von Zeichen erfassen. Stellen Sie sich vor, wir haben die Aufgabe, alle h1-h6-Überschriften-Tags und deren Inhalt zu finden, und der Rest des Texts sollte nicht betroffen sein (ich habe das nicht vorhandene h7-Tag absichtlich eingegeben, um nicht unter dem Entkommen der Habré-Tags zu leiden):

Regulärer Ausdruck: <h [1-7]>. *? <\ / H [1-7]>

Text: < h7 > Hallo </ h7 > Lorem Ipsum Avada Kedavra < h7 > kaufen < /h7 >

Alles hat erfolgreich funktioniert, aber nur dank des faulen Quantifizierers. Im Falle der Verwendung des gierigen Quantifizierers würde der gesamte Text zwischen den Tags hervorstechen (ich denke, dies erfordert keine Illustration).

Zeichenkettenrahmen

Die Grenzen von Zeichenketten haben wir bereits oben benutzt. Hier ist eine detailliertere Tabelle:

\ bWortgrenze
\ Bkeine Wortgrenze
\ AZeilenanfang
\ ZZeilenende
\ GEnde der Aktion


Mit Unterausdrücken arbeiten

Unterausdrücke in regulären Ausdrücken werden mit dem Gruppenmetazeichen () .
Hier ist ein Beispiel für einen regulären Ausdruck, mit dem universell verschiedene Variationen von IP-Adressen gefunden werden können.

Regulärer Ausdruck: (((25 [0-5]) | (2 [0-4] \ d) | (1 \ d {2}) | (\ d {1,2})) \.) {3} (((25 [0-5] | (2 [0-4] \ d) | (1 \ d {2}) | (\ d {1,2}))))

Text: 255.255.255.255 ist nur eine Adresse
191.198.174.192 wikipedia
87.240.190.67 vk
31.13.72.36 facebook

Es wird der logische Operator | (oder), mit dem wir einen regulären Ausdruck erstellen können, der der Regel entspricht, nach der IP-Adressen kompiliert werden. Die IP-Adresse muss 1 bis 3 Ziffern enthalten, wobei eine Anzahl von drei Ziffern mit 1, mit 2 (oder die zweite Ziffer muss zwischen 0 und 4 liegen) oder mit 25 und dann mit 3 Ziffern beginnen kann Es stellt sich heraus, dass der Wert zwischen 0 und 5 liegt. Außerdem muss zwischen jeder Zahlenkombination ein Punkt stehen. Versuchen Sie anhand der obigen Tabellen, den regulären Ausdruck oben zu entschlüsseln. Reguläre Ausdrücke am Anfang erschrecken Sie mit ihren langen, aber nicht komplexen.

Schau nach vorne

Um einen Ausdruck für eine beliebige Kombination bestimmter Zeichen anzuzeigen, wird ein Muster angegeben, anhand dessen eine Übereinstimmung erkannt, jedoch nicht zurückgegeben wird. Vorausschauend definiert im Wesentlichen einen Unterausdruck und wird daher entsprechend gebildet. Das Syntaxmuster für das Vorausschauen besteht aus einem Unterausdruck, dem? = Vorangestellt ist. Dann wird der zu vergleichende Text gleichermaßen befolgt.

Hierbei handelt es sich um eine bestimmte Aufgabe: Es gibt ein Kennwort, das aus mindestens 7 Zeichen bestehen und mindestens einen Großbuchstaben und eine Zahl enthalten muss. Hier wird alles etwas komplizierter, weil der Benutzer den Großbuchstaben sowohl am Anfang als auch in der Mitte des Satzes setzen kann (und dasselbe sollte mit dem Buchstaben wiederholt werden).

Deshalb müssen wir uns auf den Ausdruck freuen. Außerdem müssen wir die Zeichen in Gruppen aufteilen. Und ich möchte seine Größe von 8 auf 22 Zeichen begrenzen:

Regulärer Ausdruck: /^(?=.*[az])(?=.*[AZ])(?=.*\d)[a-zA-Z\d]{8,}$/

Text: Qwerty123
Im789098
schwaches Passwort

Funktionen der Arbeit von regulären Ausdrücken in PHP


Um zu erfahren, wie reguläre Ausdrücke in PHP funktionieren, lesen Sie die Funktionen in der offiziellen PCRE-Dokumentation (Perl Compatible Regular Expressions), die auf der offiziellen Website verfügbar ist. Der Ausdruck muss in Trennzeichen eingeschlossen sein, z. B. in Schrägstrichen.

Beliebige Zeichen können ein Trennzeichen sein, mit Ausnahme von alphanumerischen Zeichen, Backslash '\' und Null-Byte. Wenn das Trennzeichen im Muster erscheint, muss es mit einem Escapezeichen versehen werden. Kombinationen kommen als Trennzeichen von Perl: (), {}, [].

Welche Funktionen werden in PHP verwendet? Das PCRE-Paket bietet die folgenden Funktionen zur Unterstützung regulärer Ausdrücke:

  • preg_grep () - Führt eine Suche durch und gibt ein Array von Übereinstimmungen zurück.
  • preg_match () - Sucht mit regulären Ausdrücken nach der ersten Übereinstimmung
  • preg_match_all () - Führt eine globale Suche mit regulären Ausdrücken durch
  • preg_quote () - Nimmt eine Vorlage und gibt ihre maskierte Version zurück
  • preg_replace () - Führt eine Such- und Ersetzungsoperation durch
  • preg_replace_callback () - führt auch eine Such- und Ersetzungsoperation durch, verwendet jedoch Callback - eine Funktion für eine bestimmte Ersetzung
  • preg_split () - teilt eine Zeichenkette in Teilstrings auf


Mit dem Modifikator i Übereinstimmungen ohne Berücksichtigung der Groß- / Kleinschreibung angeordnet.
Mit dem Modifikator m können Sie den mehrzeiligen Textverarbeitungsmodus aktivieren.

Das Ersetzen von Strings kann als PHP-Code berechnet werden. Verwenden Sie den Modifikator e , um diesen Modus zu aktivieren.

Alle preg_split() preg_replace_callback() preg_split() und preg_split() unterstützen ein zusätzliches Argument, das die maximale Anzahl von Ersetzungen oder Partitionen einschränkt.

Backlinks können durch das $ -Zeichen (z. B. $ 1) gekennzeichnet werden, und in früheren Versionen werden die \\ -Zeichen anstelle des $ -Zeichen verwendet.
Die Metazeichen \ E, \ l, \ L, \ u und \ u werden nicht verwendet (daher wurden sie in diesem Artikel nicht erwähnt).

Unser Artikel wäre unvollständig ohne die POSIX-Zeichenklassen, die auch in PHP funktionieren (und im Allgemeinen die Lesbarkeit Ihrer Stammkunden verbessern können, aber nicht alle haben es eilig zu lernen, da sie häufig die Logik des Ausdrucks verletzen).

[[: alnum:]]Beliebiger Buchstabe des englischen Alphabets oder der Zahl
[[: alpha:]]Beliebiger Buchstabe ([a-zA-Z])
[[: blank:]]Leerzeichen oder Zeichencode 0 und 255
[[: digit:]]Beliebige Ziffer ([0-9])
[[: lower:]]Beliebiger Kleinbuchstabe des englischen Alphabets ([az])
[[: upper:]]Jeder Großbuchstabe des englischen Alphabets ([AZ])
[[: punct:]]Beliebiges Interpunktionszeichen
[[: Leerzeichen:]]Beliebiges Leerzeichen
[[: xdigit:]]Beliebige hexadezimale Ziffer ([0-9a-fA-F])


Am Ende werde ich anhand der oben genannten Implementierungen ein Beispiel für eine konkrete Implementierung regulärer Ausdrücke in PHP geben. Ich habe auch die Validierung des Benutzernamens hinzugefügt, damit er nicht zu kurze Buchstabenkombinationen eingeben kann (naja, angenommen, es handelt sich um Spitznamen, nicht um Namen, Namen sind kürzer als zwei Buchstaben):

  $pattern_name = '/\w{3,}/'; $pattern_mail = '/\w+@\w+\.\w+/'; $pattern_password = '/^(?=.*[az])(?=.*[AZ])(?=.*\d)[a-zA-Z\d]{8,}$/'; if (preg_match($pattern_name, $name) && preg_match($pattern_mail, $mail) && preg_match($pattern_password, $_POST['password'])) { #  ,  ,   ,   ,      } 


Vielen Dank für Ihre Aufmerksamkeit! Natürlich haben wir heute nur einen Teil der regulären Ausdrücke angesprochen, und einige weitere Artikel können darüber geschrieben werden. Zum Beispiel haben wir nicht über die Implementierung der Suche nach Wiederholungen identischer Wörter im Text gesprochen. Ich hoffe aber, dass das gewonnene Wissen ausreicht, um meine erste Formularvalidierung sinnvoll zu schreiben und erst dann zu wütenderen Dingen überzugehen.

Aus Tradition ein paar nützliche Links:

MIT-Spickzettel für reguläre Ausdrücke
Der offizielle Teil der PHP-Regex- Dokumentation .

Das ist alles. Wir sehen uns auf der Intensiv !
Der zweite intensive Tag wird hier stattfinden

Source: https://habr.com/ru/post/de484048/


All Articles