preg_match_all() erklärt

home php

COBOL - Altsysteme warten und erweitern. Das umfassende Praxis-Handbuch   -  Dieses Buch richtet sich an erfahrene Entwickler objektorientierter Sprachen wie C++ oder Java. Es vermittelt die Funktionsweise der Programmiersprache COBOL, um die in zahlreichen Implementierungen auf unterschiedlichen Plattformen immer noch produktiv laufenden COBOL-Programme zu verstehen, zu warten und bei Bedarf mit zusätzlichen Funktionalitäten zu erweitern. Dafür bietet es Ihnen sowohl eine grundlegende Einführung in die Programmierung mit COBOL als auch eine thematisch gegliederte Referenz der Befehle mit praktischen Beispielen.

Wir sind Mitglied im Amazon.Partnernet und können mit Affiliate-Links den Betrieb der Webseite etwas unterstützen, für Sie als Leser ist das natürlich vollkommen kostenlos.

Der beliebte PHP-Befehl preg_match_all() mit konkreten Beispielen genauer betrachtet.

Was macht preg_match_all()

Der PHP Befehl preg_match_all() untersucht einen übergebenen String auf die Existenz eines festgelegten Suchpatterns (Regular Expression). Im Gegensatz zum bekannten preg_match() liefert er alle Treffer zurück statt nur des ersten Treffers. So weit so gut, denn das kann man auch in PHP.net nachlesen. Doch zeichnet den Befehl etwas aus, was in der Dokumentation nicht so ganz deutlich wird, daher möchte ich diese Besonderheit noch einmal klarer mit einem konkreten Beispiel aus der Praxis hervorheben.

Parsing eines Textes nach numerischen Tokens

Als Demonstration, habe ich eine Aufgabenstellung aus einer CMS Programmierung, prototypisch als Codebeispiel ausgesucht. Der folgende Beispiel-Text ist angefüllt mit so genannten Tokens ala

{999}

Beispiel für einen numerischen Token

(Ziffern von 0-99999 die einen Bausteintext-ID aus einer Datenbank symbolisieren). Zur Laufzeit soll der Parser die Tokens durch die Textphrasen aus einer Datenbank ersetzen.

$data = <<<EOD
Dieser Beispieltext ist angefüllt mit so genannten Tokens, die das Programm mit einer {2468} 
RegularExpression finden und {55} einsammeln soll. Alle Tokens in Form von {0} werden in 
einem Array {3} zusammengetragen. Im Anschluss daran, soll das System diese Tokens {349} 
durch Textbausteine aus einer Datenbank ersetzen.
EOD;

Dummy Text der mit Tokens gefüllt ist die ersetzt werden sollen

Auf den oben gezeigten Heredoc-Text wende ich unterschiedliche Patterns an und zeige wie diese wirken. Besonderes Augenmerk ist dabei auf die Setzung des runden Klammerpaars () zu achten, da die Position maßgeblich für das entstehende Ergebnis-Array $matches ist.

'/{[0-9]*}/' - der Klassiker

Beginnen wir mit dem Klassiker, den man sicherlich als erstes verwenden würde, wenn man mit dieser Aufgabenstellung beginnt:

preg_match_all('/{[0-9]*}/', $data, $matches)

Typischer RegEx zum finden von {399}

Dieser Befehl erzeugt ein recht erwartbares Array wie folgt:

array(1) 
{ 
    [0]=> array(8) 
    { 
        [0]=> string(6) "{2468}" 
        [1]=> string(4) "{55}" 
        [2]=> string(3) "{0}" 
        [3]=> string(3) "{3}" 
        [4]=> string(5) "{349}"  
    } 
}

RegEx: Ergebnis Array

Die Delimiter / leiten das Pattern ein und beenden es mit /. Die RegEx findet folglich alles Stellen die numerisch {0} bis {99999...} reichen.

Tipp: Das Pattern [0-9] würde lediglich einstellige Muster finden, während [0-9]* auch mehrstellige numerische Suchmuster ermitteln kann und genau das soll ja Ziel sein.

'/({)[0-9]*(})/' - schon besser

Setzen Sie nun die geschweiften Klammern { je zwischen zwei runde Klammern, also so:

({)...(})

RegEx mit runden Klammern

erzeugt der Befehl:

preg_match_all('/({)[0-9]*(})/', $data, $matches)

RegEx Version 2

eine ganz andere Array-Struktur. Der Befehl erzeugt für jedes Paar () ein eigenes Array und ein Array mit dem Ergebnis das sich zwischen den beiden Klammerpaaren ermittelt:

array(3) 
{ 
    [0]=> array(8) 
    { 
        [0]=> string(6) "{2468}" 
        [1]=> string(4) "{55}" 
        [2]=> string(3) "{0}" 
        [3]=> string(3) "{3}" 
        [4]=> string(5) "{349}"
    } 
    [1]=> array(8) 
    { 
        [0]=> string(1) "{" 
        [1]=> string(1) "{" 
        [2]=> string(1) "{" 
        [3]=> string(1) "{" 
        [4]=> string(1) "{" 
    } 
    [2]=> array(8) 
    { 
        [0]=> string(1) "}" 
        [1]=> string(1) "}" 
        [2]=> string(1) "}" 
        [3]=> string(1) "}" 
        [4]=> string(1) "}"
    } 
}

Ergebnis-Array der RegEx

'/{([0-9]*)}/' die beste Wahl

Das gewünschte Ergebnis stellt sich für die oben gezeigte Aufgabenstellung jedoch mit diesem Pattern ein:

/{([0-9]*)}/

RegEx: numerisch extrahieren

dabei ist der numerische Anteil des Pattern geklammert und erzeugt damit ein dazu passendes Ergebnis-Array in $matches. Der folgende Befehl:

preg_match_all('/{([0-9]*)}/', $data, $matches)

RegEx: extrahieren des numerischen Anteil

führt daher zu dem volgenden Ergebnis:

array(2) 
{ 
    [0]=> array(8) 
    { 
        [0]=> string(6) "{2468}" 
        [1]=> string(4) "{55}" 
        [2]=> string(3) "{0}" 
        [3]=> string(3) "{3}" 
        [4]=> string(5) "{349}" 
    } 
    [1]=> array(8) 
    { 
        [0]=> string(4) "2468" 
        [1]=> string(2) "55" 
        [2]=> string(1) "0" 
        [3]=> string(1) "3" 
        [4]=> string(3) "349" 
    } 
}

Der numerische Teil ist geklammert und wird als eigenes Array erzeugt

Sofern also der numerische Wert im Token {399} die Textbaustein-ID eines Eintrages in einer Datenbank wiederspiegeln soll, kann mit dem Array $matches[1] darüber iteriert werden und daraus ein SELECT erzeugt werden, etwa so:

foreach($matches as $value) 
{
    $sql    = 'SELECT * FROM docbin_baustein WHERE id = '.$value;
    $result = ...
}

Verwendung der Trefferliste als ID-Geber für SELECT

Beispiel: öffnende und schließende HTML-Tags

Für die folgenden RegEx-Beispiele, soll der folgende Demotext als Quelle dienen:

<h1>Lorem Ipsum</h1>
<p class="fw-bold">Das ist der Inhalt des Beitrags für das RegEx Pattern.</p>
<h2>Dolor sit amet</h2>
<p class="fw-bold">Das ist der Inhalt des Beitrags für das RegEx Pattern.</p>

Demo-Text

Zunächst ein interessantes Pattern aus der PHP-Dokumentation:

preg_match_all("|<[^>]+>(.*)</[^>]+>|U", $data, $matches);

RegEx Pattern aus der Doku

Das oben gezeigte Pattern extrahiert alle <.> - </.> Tags aus dem Content und zerlegt die Treffer in zwei Arrays:

array(2) 
{
    [0]=> array(4) 
    {
        [0]=> string(20) "<h1>Lorem Ipsum</h1>"
        [1]=> string(78) "<p class="fw-bold">Das ist der Inhalt des Beitrags für das RegEx Pattern.</p>"
        [2]=> string(23) "<h2>Dolor sit amet</h2>"
        [3]=> string(78) "<p class="fw-bold">Das ist der Inhalt des Beitrags für das RegEx Pattern.</p>"
    }
    [1]=> array(4) 
    {
        [0]=> string(11) "Lorem Ipsum"
        [1]=> string(55) "Das ist der Inhalt des Beitrags für das RegEx Pattern."
        [2]=> string(14) "Dolor sit amet"
        [3]=> string(55) "Das ist der Inhalt des Beitrags für das RegEx Pattern."
    }
}

Ergebnis-Array der RegEx

Im Array $matches[1] kann über die reinen ASCII-Inhalte iteriert werden, während das Array $matches[0] zusätzlich die HTML-Tokens enthält. Je nach Geschmack kann eines der beiden Arrays genutzt werden.

Beispiel: H-Tags extrahieren

Im zweiten Beispiel, sollen die H-Tags extrahiert werden, dazu reicht es aus, das eingans gezeigte Pattern um h zu erweitern, also so:

preg_match_all("|<h[^>]+>(.*)</h[^>]+>|U", $data, $matches);

RegEx: H-tags extrahieren

um das folgende Ergebnis zu erhalten:

array(2) 
{
    [0]=> array(2) 
    {
        [0]=> string(20) "<h1>Lorem Ipsum</h1>"
        [1]=> string(23) "<h2>Dolor sit amet</h2>"
    }
    [1]=> array(2) 
    {
        [0]=> string(11) "Lorem Ipsum"
        [1]=> string(14) "Dolor sit amet"
    }
}

Ergebnis-Array der RegEx

Beispiel: P-Tags und class extrahieren

Im dritten Beispiel können Sie mit dem folgenden Pattern alle P-Tags und den Inhalt zwischen Start und Ende der Tags extrahieren:

preg_match_all('/<[p].*>(.*)<\/[p]>/', $data, $matches);

RegEx: P-Tags extrahieren

Mit diesem RegEx-Pattern erhalten Sie das folgende Array:

array(2) 
{
    [0]=> array(2) 
    {
        [0]=> string(78) "<p class="fw-bold">Das ist der Inhalt des Beitrags für das RegEx Pattern.</p>"
        [1]=> string(62) "<p>Das ist der Inhalt des Beitrags für das RegEx Pattern.</p>"
    }
    [1]=> array(2) 
    {
        [0]=> string(55) "Das ist der Inhalt des Beitrags für das RegEx Pattern."
        [1]=> string(55) "Das ist der Inhalt des Beitrags für das RegEx Pattern."
    }
}

Ergebnis-Array der RegEx

Sie extrahieren alle Inhalte zwischen den P-Tags in $matches[1] bzw. die vollständigen Treffermuster mit HTML-Tags in $matches[0]. Möchten Sie zudem auch noch die class="..." Spezifizierung ermitteln, dann müssen Sie ein Klammerpar in /<[p].* einfügen, folglich /<[p](.*). Mit dem Befehl:

preg_match_all('/<[p](.*)>(.*)<\/[p]>/', $data, $matches);

RegEx: zum extrahieren der P-Tags und Class-Attribute

entsteht das folgende Array:

array(3) 
{
    [0]=> array(2) 
    {
        [0]=> string(78) "<p class="fw-bold">Das ist der Inhalt des Beitrags für das RegEx Pattern.</p>"
        [1]=> string(62) "<p>Das ist der Inhalt des Beitrags für das RegEx Pattern.</p>"
    }
    [1]=> array(2) 
    {
        [0]=> string(16) " class="fw-bold""
        [1]=> string(0) ""
    }
    [2]=> array(2) 
    {
        [0]=> string(55) "Das ist der Inhalt des Beitrags für das RegEx Pattern."
        [1]=> string(55) "Das ist der Inhalt des Beitrags für das RegEx Pattern."
    }
}

Ergebnis-Array der RegEx

Folglich enthält $matches[1] alle Treffer zu den Parametern hinter dem P im öffnenden P-Tag, meist sind das Class-Parameter oder ID-Angaben.


 28.01.2024    Kontakt@Oliver-Lohse.de    preg_match RegEx Regular Expression

JavaScript das umfassende Handbuch. JavaScript objektorientiert lernen und verstehen   -  Ein umfassender Einstieg in JavaScript, viele praktische Beispiele und eine Darstellung auch professioneller Techniken - all das zeichnet dieses unverzichtbare Handbuch aus. Es eignet sich sowohl für Anfänger, die JavaScript von Grund auf lernen, als auch für Fortgeschrittene und Profis, die wissen wollen, wie man moderne, dynamische Webanwendungen entwickelt. Hier finden Sie alle wichtigen Techniken - Ajax, jQuery, Node.js, DOM und mehr. Entdecken Sie die neuesten Trends, Techniken und Entwicklungen bis hin zur Steuerung von Microcontrollern. Machen Sie sich mit Objektorientierung, ECMAScript 21 und funktionaler Programmierung vertraut und profitieren Sie von zahlreichen praxisnahen Beispielen für den sofortigen Einsatz. Das perfekte Lehrbuch für moderne Webentwickler!

Wir sind Mitglied im Amazon.Partnernet und können mit Affiliate-Links den Betrieb der Webseite etwas unterstützen, für Sie als Leser ist das natürlich vollkommen kostenlos.

Weitere passende Beiträge

Impressum


CMSWorkbench.de ist eine reine Entwickler-Webseite und dient vorwiegend als Wissensspeicher für die Entwicklung von CMS

Datenschutz


Die Webseite verwendet keinerlei Tracking- oder Speicher-Mechanismen, die Rückschlüsse auf Ihre IP oder das Leseverhalten zulassen

Affiliate


Wir sind Mitglied im Amazon Partnernet und können mit Affiliate-Links (* den Betrieb der Seite etwas unterstützen, für Sie ist das natürlich kostenlos

Kontakt


Sie können mit uns über eMail Kontakt aufnehmen, schreiben Sie an Kontakt@Oliver-Lohse.de