Rolf B: Im Sting alles mit (xxx) ersetzten

Beitrag lesen

Hallo Gunnar,

Vor ( gehört ein Leerzeichen. (Vor [ und nach ] auch.)

Es besteht eine relevante Wahrscheinlichkeit dafür, dass die Ersteller der zu parsenden Texte das nicht wissen oder drauf gepfiffen haben.

Heißt: Eine Funktion, die eingeklammerte Textteile sucht und irgendwas damit macht, sollte NICHT voraussetzen, dass die Regeln zur korrekten Leerzeichenverwendung eingehalten wurden.

Spannend wird es vor dann, wenn im zu verarbeitenden Text die Klammerschachtelung falsch ist. Also zum Beispiel: Der Mann (bekleidet mit einer [nicht löchrigen) Jeans] steht hinter dem Haus.

Mein Ansatz wäre, nach geschlossenen Klammern zu suchen (z.B. mit p = strcspn($sting, ")}]") und von dort aus rückwärts nach der passenden öffnenden Klammer (z.B. mit strrpos). Hat man auf diese Weise ein geklammertes Fragment gefunden, muss man noch prüfen ob es einer der öffnenden Klammern enthält; wenn ja, liegt ein Schachtelungsfehler vor. Wenn nicht, kann man mit dem Fragment tun, was immer nötig ist, und zwar so, dass das gefundene Klammerpaar nachher nicht mehr im Sting steht. Und danach fängt man von vorn an, solange, wie etwas gefunden wird.

Wenn geschachtelte Klammern nicht relevant sind und man das Problem falscher Schachtelung ignorieren kann (oder will), reicht auch

$matches = ARRAY();
$success = preg_match("\[.*?]|\(.*?\)|\{.*?\}", $sting, $matches, PREG_OFFSET_CAPTURE)
foreach ($matches[0] as $match) {
   echo "Finde $match[0] an Position $match[1]\n";
}

Das Pattern sucht Paare aus [], () und {}. Die Zeichen zwischen den Paaren werden non-greedy übersprungen, weil andernfalls für "[...] Hallo [...]" der ganze Sting gematcht würde. Die Treffer stehen im Index 0 des $matches Array, mit Inhalt und Startposition. Der genaue Aufbau von $matches ist relativ kompliziert und kann im Handbuch nachgelesen werden, für die vorliegende Regex gibt es aber nur den Eintrag $matches[0].

Rolf

--
sumpsi - posui - clusi