Wie kann ich das Capturen von beliebig verschachtelten Untergruppen in einer Perl-Regex-Zeichenfolge entfernen? Ich möchte jeden Regex in einen umhüllenden Ausdruck verschachteln, der den Sub-Regex als ganze Entität sowie statisch bekannte nachfolgende Gruppen erfasst. Muss ich die Regex-Zeichenfolge manuell in alle nicht-Capture (?:)
Gruppen transformieren (und hoffe, ich vermassle nicht), oder gibt es einen Perl Regex oder Bibliothek Mechanismus, der dies bietet?
Addendum: Ich bin mir vage bewusst, $&
, $'
und $'
und wurde empfohlen, sie zu vermeiden, wenn möglich, und ich habe keinen Zugriff auf ${^PREMATCH}
, ${^MATCH}
und ${^POSTMATCH}
in meiner Perl 5.8-Umgebung. Das obige Beispiel kann mit solchen Methoden in 2/3 Chunks partitioniert werden, und komplexere reale Fälle könnten dies manuell iterieren, aber ich denke, ich hätte gerne eine allgemeine Lösung, wenn möglich.
Akzeptierte Antwort: Was ich wünschte, existierte und überraschenderweise (zumindest für mich) nicht, ist eine einkapselnde Gruppe, die ihren Inhalt undurchsichtig macht, so dass nachfolgende positionelle Rückreferenzen den Inhalt als eine einzige Entität sehen und Namenreferenzen werden entfernt. gbacon hat eine potenziell nützliche Problemumgehung für Perl 5.10+ und FM zeigt einen manuellen iterativen Mechanismus für jede Version, die denselben Effekt erzielen kann spezifische Fälle, aber j_random_hacker nennt es, dass es keinen echten Sprachmechanismus zum Einkapseln von Teilausdrücken gibt.
Im Allgemeinen können Sie nicht.
Selbst wenn Sie alle (...)
s in (?:...)
s transformieren könnten, würde dies im allgemeinen Fall nicht funktionieren, weil das Muster Rückverweise erfordern könnte : z. /(.)X/
, die mit einem beliebigen Zeichen übereinstimmt, gefolgt von einem X
, gefolgt vom ursprünglich übereinstimmenden Zeichen.
Wenn also kein Perl-Mechanismus zum Verwerfen erfasster Ergebnisse "nach der Tat" zur Verfügung steht, gibt es keine Möglichkeit, Ihr Problem für alle Regexe zu lösen. Das Beste, was Sie tun können (oder tun könnten, wenn Sie Perl 5.10 hätten), ist gbacons Vorschlag und hoffe, einen eindeutigen Namen für den Capture-Puffer zu generieren.
Eine Möglichkeit zum Schutz der Untermuster, die Ihnen wichtig sind, ist benannte Aufnahmepuffer :
Zusätzlich können Sie ab Perl 5.10.0 benannte Capture-Puffer und benannte Backreferences verwenden. Die Schreibweise lautet
(?<name>...)
zum Deklarieren und\k<name>
zum Referenzieren. Sie können auch Apostrophe anstelle von spitzen Klammern verwenden, um den Namen zu begrenzen. und Sie können die geklammerte\g{name}
-Rückreferenzsyntax verwenden. Es ist auch möglich, auf einen benannten Capture-Puffer durch absolute und relative Nummer zu verweisen. Außerhalb des Musters steht ein benannter Capture-Puffer über den%+
Hash zur Verfügung. Wenn verschiedene Puffer innerhalb desselben Musters denselben Namen haben, beziehen sich$+{name}
und\k<name>
auf die am weitesten links stehende Gruppe.
Im Zusammenhang mit Ihrer Frage wird check
Dann mit
aufrufen %Vor%Ausgaben
%Vor%Perl der Version & gt; 5.22 soll einen '/ n' Modifier haben, der alle Capturing ausschaltet.