Top
PHP Tutorial – Schritt 14: RegEx und preg_replace – RonnyDee´s Blog
fade
2458
post-template-default,single,single-post,postid-2458,single-format-standard,eltd-core-1.1.1,flow child-child-ver-1.0.0,flow-ver-1.3.7,eltd-smooth-scroll,eltd-smooth-page-transitions,ajax,eltd-blog-installed,page-template-blog-standard,eltd-header-standard,eltd-fixed-on-scroll,eltd-default-mobile-header,eltd-sticky-up-mobile-header,eltd-dropdown-default,wpb-js-composer js-comp-ver-5.2.1,vc_responsive

PHP Tutorial – Schritt 14: RegEx und preg_replace

Nachdem wir uns im vorherigen Beitrag „PHP Tutorial – Schritt 13: Suchen und Ersetzen“ schon ein wenig mit RegEx auseinander gesetzt haben, geht es in diesem Beitrag weiter. Nochmal kurz zur Wiederholung, was wir bereits gelernt haben:

|

  • Einsatz und Funktionsweise von str_replace
  • Ein-Elementige reguläre Ausdrücke von RegEx
  • Mehrelementige reguläre Ausdrücke von RegEx
  • Die optionale Verwendung von Ausdrücken
  • Live Kontrolle von RegEx Code via RegExpal

|

Mehrfache Möglichkeiten

Im letzten Beispiel haben wir ja gelernt, wie wir mindestens eine Ziffer und 2 optionale Buchstaben prüfen können:

|

Was aber, wenn wir nun wissen, dass es auch mehr als 9 Gleise gibt, sprich zwei… oder gar dreistellige Gleisziffern?

Wir ergänzen unseren Code um diese Angabe

|

also in

|

Diese Zusatzangabe bewirkt nun, dass mindestens eine Ziffer vorhanden sein muss ({1) und maximal 3 Ziffern (optional) möglich sind (3}). Das heißt du kannst nun auch die Gleise 11A, 35ab, 456C usw. prüfen. Versuchs am besten gleich mal per http://regexpal.com/

|

Ein weiteres Übungsbeispiel

Wie prüfst du aber eine Hausnummer korrekt, die 1 bis 2stellig mit einem Buchstabenszusatz versehen sein kann?

Naheliegend wäre ja der Code

|

Allerdings ist dieser Code nicht ganz richtig. Er funktioniert zwar, aber dadurch erlaubst du auch Eingaben wie „0a“ oder „0c“. Und die Hausnummer „0“ (Null) gibt es eben nicht. Änderst du den Code dahingehend auf

|

…so lässt du zwar die Hausnummer „0“ (Null) nicht mehr zu, aber auch nicht die Hausnummer „20“, „30“, usw. da du die „0“ (Null) nämlich gänzlich ausgeschlossen hast.

Du siehst… man muss sich im Vorfeld einige Gedanken machen, richtig wäre z.B. der Code

|

Somit hast du nun alle Hausnummern von 1 bis 99 und von 1a bis 99z abgedeckt 🙂

Möchtest du mindestens eine 2stellige Hausnummer (ohne Buchstabenzusatz, also nur Ziffern) prüfen, so kannst du das auch so lösen:

|

Du darfst dich nur nicht beirren lassen, dass du eventuell die 0 (Null) entfernst, denn die brauchst du für die ganzen Zehnerzahlen (10, 20, 30…)

|

Beliebige Wiederholungen

Prima… wir kommen gut voran. Jetzt wirds wieder etwas knifflig. Als Beispiel dafür wollen wir nun verschiedene Formate von Telefonnummern prüfen:

  • 0651/55541-36
  • 0049 160 555678
  • 0180.23.555.63

|

Eine echte Katastrophe, oder?

Telefonnummern in einem gemischten Format sind der Overkill für jeden der mit Daten arbeitet. In diesem Fall haben wir Ziffern, Leerzeichen, Bindestriche, Punkte und auch einen Schrägstrich.

Der erste Ansatz wäre also folgender Code (denn darin haben wir nun alle Ausnahmen reingepackt):

Achtung, der Bindestrich (-) am Ende wird nicht als Bindestrich angesehen, sondern als Bereichsdefinierer, wie z.B. bei den Ziffern 0-9 (also Null BIS Neun)

|

Der Bindestrich muss also maskiert werden. Dies können wir mit einem vorangestellten Backslash () erreichen:

|

Jetzt möchten wir natürlich auch noch, dass nicht nur ein (1) Zeichen vorkommen darf, sondern beliebig viele. Dies ermöglicht das Plus (+) am Ende:

|

Das Plus sagt aus, dass die vorangestellten Zeichen (in der Klammer) mindestens 1x vorkommen müssen. Egal welches.

Möchten wir das „mindestens 1x“ gegen „optional 1x“ austauschen, also „gar nicht“ bis „beliebig oft“, so tauschen wir das Plus (+) gegen ein Sternchen (*):

|

Platzhalter

Verlassen wir doch mal den Klammerbereich ([]) und gehen auf „normale“ Abfragen über.

Möchtest du z.B. in einer Liste nach einem Namen suchen, weißt aber nicht genau ob es noch einen zweiten Vornamen gibt, dann würde die Abfrage dazu (sofern du den ersten Vornamen und auch den Nachnamen genau kennst) so aussehen:

|

In diesem Fall bewirkt die Abfrage, dass du nach folgendem suchst:

  • Die ersten 5 Zeichen lauten „Ronny“
  • dann kommt ein Leerzeichen
  • dann ein beliebiges Zeichen (das drückt der Punkt „.“ aus)
  • und das beliebige Zeichen entweder „niemals“ oder „beliebig oft“ (das drückt das Sternchen (*) aus)
  • und das Ende der Zeichenkette soll mit „Dechler“ enden

|

Zeichen ausschließen/negieren

Natürlich können wir auch sagen, es gibt sicher einen zweiten Vornamen und er hat zu 100%iger Sicherheit gewisse Buchstaben nicht enthalten. Das ginge dann mit diesem Code:

|

In diesem Fall bewirkt die Abfrage, dass du nach folgendem suchst:

  • Die ersten 5 Zeichen lauten „Ronny“
  • dann kommt ein Leerzeichen
  • dann mindestens 1 Zeichen (wegen dem Plus (+)) das aber die Zeichen (r, q und z) nicht enthält (wegen dem Zirkumflex (^))
  • dann wieder ein Leerzeichen (!)
  • und das Ende der Zeichenkette soll mit „Dechler“ enden

|

Klammern

Solltest du dir wegen dem zweiten Vornamen sogar sicher sein das es ihn gibt, aber nicht sicher sein, ob er auch in der Liste eingetragen ist, so kann man diesen Fall folgendermaßen abfangen:

|

Dadurch bewirkt die Abfrage, dass du nach folgendem suchst:

  • Die ersten 5 Zeichen lauten „Ronny“
  • dann kommt ein Leerzeichen
  • dann kommt der optionale Suchstring „RonnyDee “ (mit Leerzeichen!)
    • Das Leerzeichen musst du in diesem Fall zum optionalen zweiten Vornamen hinzufügen, machst du das nicht, so suchst du nach „Ronny  Dechler“ (2x Leerzeichen) und das führt zu Fehlern
  • und das Ende der Zeichenkette soll mit „Dechler“ enden

|

Mit Klammern kann man auch Platzhaltern kann man auch sowas machen:

|

Das heißt, du findest stets Treffer zu diesen Wörtern:

  • Bane
  • Banane
  • Banananane
  • usw.

|

Warum? Weil du „Ba“ am Anfang und „ne“ am Ende voraussetzt. Dazwischen kann entweder „nicht“ oder „so oft wie möglich“ die Folge „na“ vorkommen (durch „(na)*“).

Man könnte es aber auch begrenzen:

|

In diesem Fall findest du nur Treffer zu diesen Wörtern:

  • Bananane
  • Banananane
  • Bananananane
  • Banananananane

|

Denn du begrent mit „(na){2,5}“ die Mindest- und Maximalanzahl von „na“. Mindestens 2x oder maximal 5x „na“.

|

Alternativen

Die Optionen nach denen du nun mittlerweile suchen kannst, sind recht groß geworden, oder? Mit RegEx kannst du sogar nach Alternativen suchen, sprich ein Wort von einer ganzen Wörterreihe kann vorkommen:

|

Somit kann der Satz „Der Sommer 2014 ist toll“ oder auch „Der Sommer 2014 ist richtig schlecht“ heißen. Nicht beide gleichzeitig.

Modifikatoren

So, jetzt möchte ich noch kurz die Modifikatoren von RegEx ansprechen. Den Rest sehen wir uns eventuell später einmal an. Mir raucht jedoch schon der Kopf 😉

|

Modifikatoren sind so gesehen Zusatzschalter die du bei diversen Abfragen aktivieren kannst. Sie wirken sich stets auf den gesamten Ausdruck (also das was wir so bisher gelernt haben) aus! Deshalb können sie einen recht oft Kopfzerbrechen bereiten, weil man diesen Umstand hin und wieder vergißt.

|

Dabei sind „i“ und „m“ in diesem Fall bereits Modifikatoren. Oft verwendete Modifikatoren sind z.B.:

  • i Case-Insensitivity (damit wird die Nichtbeachtung von Groß- und Kleinschreibung eingeschaltet)
  • s Punkt wird multilinefähig: Der Punkt (steht für ein x-beliebiges Zeichen) „frisst“ auch Zeilenumbrüche, dies ist standardmäßig nicht so.
  • m Zeilenmodus: Die Zeichen ^ und $ passen auch auf Zeilenanfänge bzw. -enden. Ohne den Modifikator passen sie nur auf Anfang und Ende der gesamten Zeichenkette.

|

Genug.
Was für eine graue Theorie, oder? Und wozu das ganze? Nun… diese Optionen, Zeichenketten, Platzhalter und wie sie alle heißen, benötigst du um den Befehl „preg_replace“ korrekt verwenden zu können. Beispiele dazu sehen wir uns im nächsten Beitrag an.

|

photo credit: martineno via photopin cc

No Comments

Post a Comment