Ich versuche, einen regulären Ausdruck zum Teilen einer Zeichenfolge zu erstellen, aber leider sind meine Anforderungen ein wenig komplexer als eine einfache Aufteilung, so dass ich zum Beispiel preg_split()
in PHP nicht verwenden kann.Extraneous Empty Trailing Match
Also was ich tue, ist die Übereinstimmung meiner Begrenzer (oder vielmehr, Teil von ihnen) in einem Unterausdruck und alles davor in einem anderen Unterausdruck, und auch das Ende der Zeichenfolge als Trennzeichen dafür zu behandeln Zweck. Vor diesem Hintergrund kam ich mit dem Follow-up:
([^?;]*)(?|\?([0-9]*)|(;)|$)
Wie Sie hoffentlich sehen können, das erste Untermuster für einen Textblock sieht ohne Fragezeichen der Semikolons. Danach habe ich ein Untermuster, das mit einem beliebigen Fragezeichen mit einer optionalen Zahl übereinstimmt (die gespeichert wird), entweder das oder ein Semikolon (das gespeichert wird) oder das Ende der Zeichenkette.
Das Problem ist, dass ich scheine ein Fremd, leer, Match gegen das Ende des String Fall zu bekommen, etwa so:
$sql = 'CALL foo(?0, ?1, ?2, ?3)';
preg_match_all('/([^?;]*)(?|\?([0-9]*)|(;)|$)/', $sql, $matches);
print_r($matches);
Ausgabe erzeugt, die wie folgt aussieht:
Array
(
[0] => Array
(
[0] => CALL insert_host(?0
[1] => , ?1
[2] => , ?2
[3] => , ?3
[4] =>)
[5] =>
)
[1] => Array
(
[0] => CALL insert_host(
[1] => ,
[2] => ,
[3] => ,
[4] =>)
[5] =>
)
[2] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] =>
[5] =>
)
)
Hinweis das leere Spiel unter $matches[0][5]
; Ich hätte erwartet, dass das Ende des String-Cases nach dem Anpassen der Klammer erfüllt wird, was zu keinem weiteren Matching führt, aber es ist weiter gegangen, um ein weiteres Match zu produzieren, und ich kann nicht herausfinden, warum.
Also meine Frage ist; Warum wird hier ein zusätzliches Spiel erstellt und wie verhindere ich es?
HINWEIS: Ich habe bereits in Erwägung gezogen, dass das Ende des String Case mindestens ein Zeichen davor haben muss, aber das ist nicht gut, da ich tatsächlich ein leeres Ergebnis haben möchte, wenn ein Wildcard auf der Seite ist string, weil ich versuche, das Verhalten einer Split-Funktion zu emulieren. Zum Beispiel, wenn die Eingabe SELECT ?
wäre, würde ich erwarten, dass SELECT ?
plus eine leere Zeichenfolge übereinstimmen. Die Idee hier ist, dass, sobald ich alle abgeglichenen Semikolons bearbeitet habe, ich einfach implode('?', $matches[1])
machen kann, um die Aussage mit numerischen Wildcards zu reproduzieren.