preg_match_all()
In PHP sind reguläre Ausdrücke ein unverzichtbares Werkzeug. Die Funktion preg_match_all() findet alle Vorkommen eines Musters in einem String.
Einführung
In PHP sind reguläre Ausdrücke unverzichtbar für die Suche und Bearbeitung von Strings. Während preg_match() beim ersten Treffer stoppt, durchsucht preg_match_all() den gesamten String und gibt jedes Vorkommen eines Musters zurück. Verwende diese Funktion, wenn du alle Telefonnummern, alle Tags, alle Wörter oder eine beliebige wiederkehrende Struktur aus einem Text extrahieren möchtest.
Dieser Artikel erklärt die Syntax, das wichtige $flags-Argument, das die Anordnung der Ergebnisse steuert, sowie mehrere praktische Beispiele.
Syntax
preg_match_all(
string $pattern,
string $subject,
array &$matches = null,
int $flags = PREG_PATTERN_ORDER,
int $offset = 0
): int|false$pattern— der reguläre Ausdruck, begrenzt durch/.../(oder beliebige passende Begrenzer).$subject— der zu durchsuchende String.$matches— ein Ausgabe-Array (per Referenz übergeben), das mit allen gefundenen Treffern gefüllt wird.$flags— optional. Steuert, wie$matchesstrukturiert wird (siehe unten).$offset— optional. Byte-Offset in$subject, ab dem die Suche beginnt.
Die Funktion gibt die Anzahl der vollständigen Muster-Treffer zurück (kann 0 sein), oder false, wenn das Muster ungültig ist.
Ein einfacher Treffer
Die grundlegendste Verwendung besteht darin, jeden Teilstring zu erfassen, der einem Muster entspricht. Hier extrahieren wir alle Zahlen aus einem Satz:
<?php
$subject = 'Room 12, floor 3, building 7';
$count = preg_match_all('/\d+/', $subject, $matches);
echo "Found $count numbers\n";
print_r($matches[0]);Ausgabe:
Found 3 numbers
Array
(
[0] => 12
[1] => 3
[2] => 7
)Wenn das Muster keine Erfassungsgruppen enthält, enthält $matches[0] die Liste der vollständigen Treffer.
Ein Flag wählen: PREG_PATTERN_ORDER vs. PREG_SET_ORDER
Das Argument $flags bestimmt, wie Treffer und Erfassungsgruppen organisiert werden. Die zwei Hauptflags schließen sich gegenseitig aus:
PREG_PATTERN_ORDER(Standard) —$matches[0]enthält alle vollständigen Treffer,$matches[1]alle Erfassungen von Gruppe 1,$matches[2]alle Erfassungen von Gruppe 2 usw. Denke daran als "spaltenweise."PREG_SET_ORDER—$matches[0]ist der erste vollständige Treffer (vollständiger Treffer + seine Gruppen),$matches[1]ist der zweite usw. Denke daran als "zeilenweise."
Du kannst auch PREG_OFFSET_CAPTURE hinzufügen, um den Byte-Offset jedes Treffers zusammen mit seinem Text aufzuzeichnen.
PREG_SET_ORDER (Ergebnisse nach Vorkommen gruppieren)
Diese Anordnung ist am einfachsten zu durchlaufen, wenn jeder Treffer mehrere Erfassungsgruppen hat:
Ausgabe:
Name: Alice, Age: 25
Name: Bob, Age: 30Mit PREG_SET_ORDER ist jedes $match ein Vorkommen: $match[0] ist der vollständige Treffer, $match[1] ist die erste Gruppe (Name), $match[2] ist die zweite Gruppe (Alter).
PREG_PATTERN_ORDER (Ergebnisse nach Muster gruppieren)
Dasselbe Muster mit dem Standard-Flag gibt die Gruppen als parallele Arrays zurück:
<?php
$pattern = '/([A-Z][a-z]+) (\d+)/';
$subject = 'Alice 25 Bob 30';
preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER);
print_r($matches[1]); // all names
print_r($matches[2]); // all agesAusgabe:
Array
(
[0] => Alice
[1] => Bob
)
Array
(
[0] => 25
[1] => 30
)Benannte Erfassungsgruppen
Das Benennen von Gruppen mit (?<name>...) macht das Ergebnis selbstdokumentierend — die Namen werden zu Array-Schlüsseln (zusätzlich zu den numerischen Indizes):
<?php
$pattern = '/(?<name>[A-Z][a-z]+) (?<age>\d+)/';
$subject = 'Alice 25 Bob 30';
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
echo "{$match['name']} is {$match['age']}\n";
}Ausgabe:
Alice is 25
Bob is 30Häufige Fallstricke
- Prüfe den Rückgabewert, nicht das Array. Ein Muster kann null Mal übereinstimmen und trotzdem erfolgreich sein;
preg_match_all()gibt dann0zurück, währendfalsebedeutet, dass der reguläre Ausdruck selbst ungültig ist. Verwende=== false, um Fehler zu erkennen. Siehepreg_last_error()für den spezifischen Fehlergrund. $matcheswird überschrieben. Jeder Aufruf ersetzt den vorherigen Inhalt des Ausgabe-Arrays.- Wähle das richtige Flag für deine Schleife. Verwende
PREG_SET_ORDER, wenn du eine Zeile pro Treffer möchtest; verwende das Standard-FlagPREG_PATTERN_ORDER, wenn du eine Spalte pro Gruppe möchtest. - Escape-Sonderzeichen in dynamischen Mustern mit
preg_quote(), wenn das Muster aus Benutzereingaben stammt.
Fazit
preg_match_all() gibt jeden Treffer eines Musters in einem String zurück und ist damit die bevorzugte Funktion zum Extrahieren wiederkehrender Daten. Der Schlüssel zur richtigen Verwendung liegt im Verständnis des $flags-Arguments: PREG_SET_ORDER gruppiert Ergebnisse nach Vorkommen, während das Standard-Flag PREG_PATTERN_ORDER sie nach Erfassungsgruppe gruppiert.
Für verwandte Funktionen siehe preg_match() für einen einzelnen Treffer, preg_replace() für Suchen und Ersetzen sowie preg_split() zum Aufteilen von Strings anhand eines Musters.