Dies wird nur die zurückgeben zuletzt Spiel für die Fanggruppe 2: DD.
Gibt es eine Möglichkeit, alle Teilmustererfassungen abzurufen (AA, BB, DD) mit einer Regex-Ausführung? Ist nicht preg_match_all dafür geeignet?
Diese Frage ist eine Verallgemeinerung.
Beide $subject und $pattern sind vereinfacht. Natürlich mit so der allgemeinen Liste von AA, BB, .. ist viel einfacher mit anderen Funktionen zu extrahieren (zB explode) oder mit einer Variation des $pattern.
Aber ich frage ausdrücklich, wie alle Untergruppenübereinstimmungen mit zurückgegeben werden können preg_...-Familie von Funktionen.
Stellen Sie sich für einen realen Fall vor, Sie haben mehrere (verschachtelte) Ebenen einer abweichenden Menge von Untermusterübereinstimmungen.
Beispiel
Dies ist ein Beispiel in Pseudocode, um ein wenig den Hintergrund zu beschreiben. Sich vorstellen die folgende:
Regelmäßige Definitionen von Token:
CHARS := [a-z]+
PUNCT := [.,!?]
WS := [ ]
$subject Get wird basierend auf diesen tokenisiert. Die Tokenisierung wird in einem Array von Tokens (Typ, Offset, …) gespeichert.
Dieses Array wird dann in eine Zeichenfolge umgewandelt, die ein Zeichen pro Token enthält:
CHARS -> "c"
PUNCT -> "p"
WS -> "s"
Damit ist es jetzt möglich, reguläre Ausdrücke basierend auf Token (und nicht Zeichenklassen usw.) auf dem Token-Stream-String-Index auszuführen. Z.B
regex: (cs)?cp
um eine oder mehrere Zeichengruppen gefolgt von einem Satzzeichen auszudrücken.
Da ich nun selbst definierte Tokens als Regex ausdrücken kann, war der nächste Schritt der Aufbau der Grammatik. Dies ist nur ein Beispiel, das ist eine Art ABNF-Stil:
words = word | (word space)+ word
word = CHARS+
space = WS
punctuation = PUNCT
Wenn ich jetzt die Grammatik für kompiliere Wörter In eine (Token-)Regex möchte ich natürlich alle Subgroup-Matches von jedem haben Wort.
words = (CHARS+) | ( (CHARS+) WS )+ (CHARS+) # words resolved to tokens
words = (c+)|((c+)s)+c+ # words resolved to regex
Bis zu diesem Punkt konnte ich codieren. Dann stieß ich auf das Problem, dass die Untergruppenspiele nur ihr letztes Spiel enthielten.
Ich habe also die Möglichkeit, entweder selbst einen Automaten für die Grammatik zu erstellen (was ich verhindern möchte, um die Grammatikausdrücke generisch zu halten) oder preg_match irgendwie für mich zum Laufen zu bringen, damit ich mir das ersparen kann.
Das ist im Grunde alles. Wahrscheinlich ist es jetzt verständlich, warum ich die Frage vereinfacht habe.
Erhalten Sie wiederholte Übereinstimmungen mit preg_match_all()
Wenn Sie Ihre Frage so verallgemeinern, dass alternative, aber richtige Antworten gegeben werden können, ist Ihre Frage nicht so wertvoll. Vereinfachen Sie nicht, wenn Sie die vereinfachten Antworten nicht wollen. -1.
– Beere Langerak
16. Juni 11 um 12:04 Uhr
Ich suche eine Antwort zu einem bestimmten Thema. Ich sehe nicht ein, warum Vereinfachung schlecht sein sollte, um dies sichtbar zu machen, obwohl ich sehe, dass ein gewisses Maß an Abstraktheit eine Belastung sein kann.
– hakre
16. Juni 11 um 12:10 Uhr
Nun, offensichtlich, weil Sie eine Antwort auf eine Untergruppe wünschen, während Ihr Beispiel die Notwendigkeit einer Untergruppe nicht beinhaltet. Das Beispiel ist fehlerhaft.
– Beere Langerak
16. Juni 11 um 12:24 Uhr
@Berry Langerak: Bei der Vereinfachung geht immer etwas verloren. Ein ausführlicheres Beispiel finden Sie jetzt hinzugefügt.
– hakre
16. Juni 11 um 12:55 Uhr
Gerade drüber gestolpert: J (PCRE_INFO_JCHANGED) – Der (?J) internal Optionseinstellung ändert die local PCRE_DUPNAMES Möglichkeit. Erlauben Sie doppelte Namen für Teilmuster, was dies hier möglicherweise nicht löst, aber im Allgemeinen interessant ist: php.net/manual/en/reference.pcre.pattern.modifiers.php
– hakre
30. August 11 um 20:53 Uhr
Benutzer109764
Ähnlicher Thread: Wiederholte Übereinstimmungen mit preg_match_all() erhalten
Überprüfen Sie die gewählte Antwort und meine könnte nützlich sein. Ich werde sie dort duplizieren:
Per Kommentar, die Ruby-Regex, die ich erwähnt habe:
sentence = %r{
(?<subject> cat | dog ){0}
(?<verb> eats | drinks ){0}
(?<object> water | bones ){0}
(?<adjective> big | smelly ){0}
(?<obj_adj> (g<adjective>s)? ){0}
Thesg<obj_adj>g<subject>sg<verb>sg<opt_adj>g<object>
}x
md = sentence.match("The cat drinks water");
md = sentence.match("The big dog eats smelly bones");
Aber ich denke, Sie brauchen einen Lexer/Parser/Tokenizer, um dasselbe in PHP zu tun. 😐
Bitte lesen Sie das längere Beispiel am Ende. Ich interessiere mich wirklich für den Untergruppenmusterabgleich über einen vollständigen Vergleich, der mir das Schreiben eines Parsers für Gruppen und die Wiederholung der BNF-Grammatik erspart. Daher brauche ich alle (Unter-) Übereinstimmungen, während ich das gesamte Thema verbrauche. preg_match_all wird von seinen Untermustern immer die letzte Übereinstimmung zurückgeben, wenn diese eine Wiederholung haben kann.
– hakre
16. Juni 11 um 18:42 Uhr
Ich denke, was Sie versuchen, ist mit benannten Gruppen und einer rekursiven Regex erreichbar, aber ich bin mir nicht sicher, ob PHP letzteres unterstützt. Möglicherweise können Sie es jedoch in Ruby verwalten.
– Denis de Bernardy
16. Juni 11 um 18:52 Uhr
Ich werde es heute Abend ein bisschen kauen.
– Denis de Bernardy
16. Juni 11 um 19:03 Uhr
Übrigens, was ist falsch an der Idee, Folgendes zu tun: $pattern = '/regex1|regex2/' in meinem obigen Vorschlag? Sie müssten wohl jeden auf Interpunktion testen, aber zumindest werden sie richtig aufgeteilt und die einzelnen Wort-/Punktgruppen werden extrahiert, oder?
– Denis de Bernardy
16. Juni 11 um 19:08 Uhr
Nein, weil es Grammatik ist: Es gibt mindestens eine Gruppe pro Wort und es gibt die Semantik der Wörter, die zusammen das nächste Wort der Grammatik bilden. Es ist also gestapelt. Und es ist mit optionaler Wiederholung innerhalb dieser Stapel. Wenn ich also nur die Daten der Spiele abrufen könnte, wäre das perfekt. Es wird jedoch nur die letzte Rückwärtsreferenz zurückgegeben. wäre cool, einen Stapel von Rückverweisen auch nach der Regex-Ausführung zu haben.
– hakre
16. Juni 11 um 19:27 Uhr
Sie können die Teilmuster nicht extrahieren, da die Art und Weise, wie Sie Ihre Regex geschrieben haben, nur eine Übereinstimmung zurückgibt (mit ^ und $ gleichzeitig und + auf dem Hauptmuster).
Wenn Sie es so schreiben, sehen Sie, dass Ihre Untergruppen dort korrekt sind:
$pattern = '/(([a-z]+) )/i';
(Dies hat immer noch unnötige Klammern, ich habe es nur zur Veranschaulichung dort gelassen.)
moteutsch
Bearbeiten
Mir war nicht klar, wonach Sie ursprünglich gefragt hatten. Hier die neue Lösung:
Wenn Sie Ihre Frage so verallgemeinern, dass alternative, aber richtige Antworten gegeben werden können, ist Ihre Frage nicht so wertvoll. Vereinfachen Sie nicht, wenn Sie die vereinfachten Antworten nicht wollen. -1.
– Beere Langerak
16. Juni 11 um 12:04 Uhr
Ich suche eine Antwort zu einem bestimmten Thema. Ich sehe nicht ein, warum Vereinfachung schlecht sein sollte, um dies sichtbar zu machen, obwohl ich sehe, dass ein gewisses Maß an Abstraktheit eine Belastung sein kann.
– hakre
16. Juni 11 um 12:10 Uhr
Nun, offensichtlich, weil Sie eine Antwort auf eine Untergruppe wünschen, während Ihr Beispiel die Notwendigkeit einer Untergruppe nicht beinhaltet. Das Beispiel ist fehlerhaft.
– Beere Langerak
16. Juni 11 um 12:24 Uhr
@Berry Langerak: Bei der Vereinfachung geht immer etwas verloren. Ein ausführlicheres Beispiel finden Sie jetzt hinzugefügt.
– hakre
16. Juni 11 um 12:55 Uhr
Gerade drüber gestolpert:
J (PCRE_INFO_JCHANGED)
– Der(?J)
internal Optionseinstellung ändert die localPCRE_DUPNAMES
Möglichkeit. Erlauben Sie doppelte Namen für Teilmuster, was dies hier möglicherweise nicht löst, aber im Allgemeinen interessant ist: php.net/manual/en/reference.pcre.pattern.modifiers.php– hakre
30. August 11 um 20:53 Uhr