2008-10-15 12 views
8

Ich habe Probleme mit Perl grep() mit einer Zeichenfolge, die kann enthalten Zeichen, die als Quantifizierer für reguläre Ausdrücke interpretiert werden.Gibt es eine Perl-Funktion, um einen String in einen Regexp zu verwandeln, um diesen String als Muster zu verwenden?

Ich bekam den folgenden Fehler, wenn das Grep-Muster "g ++" ist, weil die '+' Symbole als Quantifizierer interpretiert werden. Hier ist die Ausgabe von für Programm, das folgt:

1..3 
ok 1 - grep, pattern not found 
ok 2 - grep, pattern found 

Nested quantifiers in regex; marked by <-- HERE 
in m/g++ <-- HERE/at escape_regexp_quantifier.pl line 8. 

Gibt es einen Modifikator ich, um anzuzeigen, verwenden könnte grep, dass die quantifiers ignoriert werden sollen, oder gibt es eine Funktion, die die quantifiers entweichen würde?

#! /usr/bin/perl 

sub test_grep($) 
{ 
    my $filter = shift; 
    my @output = ("-r-xr-xr-x 3 root  bin  122260 Jan 23 2005 gcc", 
        "-r-xr-xr-x 4 root  bin  124844 Jan 23 2005 g++"); 
    return grep (!/$filter/, @output); 
} 

use Test::Simple tests => 2; 

ok(test_grep("foo"), "grep, pattern not found"); 
ok(test_grep("gcc"), "grep, pattern found"); 
ok(test_grep("g++"), "grep, pattern found"); 

PS: zusätzlich zu der Antwort Frage oben, ich begrüße jedes Feedback auf Perl Verwendung in der oben als ich noch lernen. Dank

Antwort

27

Der üblicher Weg ist, um die \Q Escape-Anzeige, bevor Sie Ihre Variable zu verwenden, Perl zu sagen, nicht den Inhalt als regulärer Ausdruck zu analysieren:

return grep (!/\Q$filter/, @output); 

ändern Sie diese Zeile im Code ergibt:

 
1..3 
ok 1 - grep, pattern not found 
ok 2 - grep, pattern found 
ok 3 - grep, pattern found 
+0

Hinweis \ Q endet bei \ E, sollte wahrscheinlich sicherstellen, dass \ E im Inhalt ist escaped. – Hasturkun

+0

Sie müssen nicht - \ E im * interpolierten * Muster verursacht keine Probleme. – hexten

15

ich glaube, Sie suchen quotemeta

+0

Ja, das war der Begriff, den ich vermisst habe, danke. – philant

8

zusätzlich zu der Antwort Frage oben, ich w Ich freue mich über jede Rückmeldung zur Verwendung von Perl in den oben genannten, da ich noch lerne. Danke

Ich würde dir raten, keine Prototypen zu verwenden (die ($) nach test_grep). Sie haben ihren Nutzen, aber nicht in den meisten Fällen und definitiv nicht in diesem.

+0

Können Sie das näher ausführen?Ich habe diesen Rat noch nie zuvor gesehen. – Alnitak

+0

Siehe http://stackoverflow.com/questions/297034/why-are-perl-function-prototypes-bad – cjm

2

PS: zusätzlich zu der Antwort Frage oben, ich begrüße jedes Feedback auf Perl Verwendung in der oben als ich noch Lernen bin.

Der beste Rat, den ich für Perl-Codierung Beratung im Allgemeinen geben kann, ist Perl::Critic zu installieren und den perlcritic Befehl auf Ihrem Code verwenden. Wenn Sie das nicht können, können Sie on-line perl critic tool verwenden. Es wird helfen, wenn Sie eine Kopie von Perl Best Practices handlich haben, da Perl::Critic das Buch bereits gelesen hat und Ihnen Verweise auf Seitenzahlen geben wird, aber selbst wenn Sie das Buch nicht herum haben, können Sie noch erweiterte Rückmeldungen in den Perl::Critic documentation Abschnitten finden mit Perl::Critic::Policy::.

2

Ich würde vorschlagen, mit Qr Regexp Objekte anstatt Strings in diesem Fall sowieso zu erstellen.

ok(test_grep(qr/foo/), "grep, pattern not found"); 
ok(test_grep(qr/gcc/), "grep, pattern found"); 
ok(test_grep(qr/g\+\+/), "grep, pattern found"); 

Dann brauchen Sie die \ Q Escape nicht. Obwohl Sie es immer noch verwenden können:

Verwandte Themen