Perl: Verwendung von String-Variablen als Suchmuster und Ersatz in Regex

8

Ich möchte String-Variablen sowohl für das Suchmuster als auch für den Ersatz in Regex verwenden. Die erwartete Ausgabe ist wie folgt,

%Vor%

Aber wenn ich das Muster und die Ersetzung zu einer Variablen verschoben habe, wurde nicht ausgewertet.

%Vor%

Wenn ich "ee" Modifier verwende, gibt es Fehler.

%Vor%

Was vermisse ich hier?

Bearbeiten

Sowohl $p als auch $r werden von mir selbst geschrieben. Was ich brauche, ist, mehrere ähnliche Regex-Ersetzungen durchzuführen, ohne den Perl-Code zu berühren, also müssen $p und $r in einer separaten Datendatei sein. Ich hoffe, dass diese Datei später mit C ++ / Python-Code verwendet werden kann. Hier sind einige Beispiele für $p und $r .

%Vor%     
kangshiyin 22.12.2016, 09:44
quelle

1 Antwort

9

Mit $p="b(.)d"; erhalten Sie eine Zeichenkette mit den Buchstaben b(.)d . Im Allgemeinen werden Regex-Muster in Strings in Anführungszeichen nicht beibehalten und haben möglicherweise nicht die erwartete Bedeutung in einer Regex. Siehe jedoch Hinweis am Ende.

Dies ist der qr-Operator für: $p = qr/b(.)d/; bildet den String als ein regulärer Ausdruck.

Wie für das Ersatzteil und /ee besteht das Problem darin, dass $r zuerst ausgewertet wird, um __ zu erhalten, was dann als Code ausgewertet wird. Leider ist das kein gültiger Perl-Code. Die _ sind barewords und sogar selbst ist nicht gültig (zum Beispiel wäre . ).

Die bereitgestellten Beispiele für $r haben $N s auf verschiedene Weise mit Text gemischt. Eine Möglichkeit, dies zu analysieren, besteht darin, alle $N und alles andere in eine Liste zu extrahieren, die ihre Reihenfolge von der Zeichenkette erhält. Dann kann das in eine Zeichenfolge verarbeitet werden, die ein gültiger Code ist. Zum Beispiel brauchen wir

%Vor%

was gültiger Perl-Code ist, der ausgewertet werden kann.

Der Teil der Aufgliederung wird durch die Teilung im Separator-Muster unterstützt.

> %Vor%

Beim Erfassen des Musters /(...)/ in split werden die Trennzeichen als Teil der Liste zurückgegeben. Somit extrahiert dies aus $r ein Array von Termen, die entweder $N oder andere sind, in ihrer ursprünglichen Reihenfolge und mit allem (anderen als nachfolgenden Leerzeichen). Dies schließt mögliche (führende) leere Zeichenfolgen ein, so dass diese herausgefiltert werden müssen.

Dann wird jeder andere Term als $N s in '...' eingeschlossen. Wenn sie alle mit . verbunden sind, erhalten wir einen gültigen Perl-Ausdruck, wie im obigen Beispiel.

Dann wird /ee diese Funktion haben, um die Zeichenfolge zurückzugeben (wie oben) und sie als gültigen Code auszuwerten.

Uns wurde gesagt, dass die Sicherheit der Verwendung von /ee bei externer Eingabe keine Sorge ist. Dies ist jedoch etwas zu beachten. Siehe diesen Beitrag , bereitgestellt von Håkon Hægland in einem Kommentar. Zusammen mit der Diskussion leitet es uns auch zu String :: Substitution . Seine Verwendung wird in diesem Beitrag demonstriert. Eine andere Möglichkeit, dies zu erreichen, ist mit replace von Data :: Munge

Weitere Informationen zu /ee finden Sie unter diesen Beitrag , mit einigen nützlichen Antworten.

Hinweis zur Verwendung von "b(.)d" für ein Regex-Muster

In diesem Fall wird mit parens und dot ihre spezielle Bedeutung beibehalten. Vielen Dank an kangshiyin für eine baldige Erwähnung und an Håkon Hægland um es zu behaupten. Dies ist jedoch ein Sonderfall. Bei Strings mit doppelten Anführungszeichen werden viele Muster direkt abgelehnt, da die Interpolation ausgeführt wird. Beispiel: "\w" ist nur ein escaped w (was nicht erkannt wird). Die einzelnen -Anführungszeichen sollten funktionieren, da keine Interpolation vorhanden ist. Strings, die als Regex-Muster verwendet werden sollen, werden am besten mit qr gebildet, da wir eine echte Regex erhalten. Dann können alle Modifikatoren ebenfalls verwendet werden.

    
zdim 22.12.2016, 09:57
quelle

Tags und Links