2009-12-22 3 views
13

Gibt es eine integrierte Möglichkeit, um eine Zeichenkette zu umgehen, die in/als regulärer Ausdruck verwendet wird? Z.B.Wie kann ich eine literale Zeichenfolge umgehen, die ich in einen regulären Ausdruck interpolieren möchte?

www.abc.com 

Die maskierte Version wäre:

www\.abc\.com 

ich wollte:

$string =~ s/[.*+?|()\[\]{}\\]/\\$&/g; # Escapes special regex chars 

Aber ich wollte nur sicherstellen, dass es nicht ein sauberer Einbau-Betrieb, dass Ich vermisse?

+1

Ich antwortete auch dies in http://stackoverflow.com/questions/1893067/how-can-i-match-in-a-regular-expression/1894320#1894320 –

+1

mögliche Duplikat von [Wie handle ich Sonderzeichen in einem Perl regex?] (http://stackoverflow.com/questions/576435/how-doi-handle-special-characters-in-a-perl-regex) – daxim

Antwort

30

Verwenden Sie quotemeta oder \Q...\E.

Betrachten Sie das folgende Testprogramm, das gegen $str übereinstimmt, wie sie ist, mit quotemeta und mit \Q...\E:

#! /usr/bin/perl 

use warnings; 
use strict; 

my $str = "www.abc.com"; 

my @test = (
    "www.abc.com", 
    "www/abc!com", 
); 

sub ismatch($) { $_[0] ? "MATCH" : "NO MATCH" } 

my @match = (
    [ as_is => sub { ismatch /$str/ } ], 
    [ qmeta => sub { my $qm = quotemeta $str; ismatch /$qm/ } ], 
    [ qe => sub { ismatch /\Q$str\E/ } ], 
); 

for (@test) { 
    print "\$_ = '$_':\n"; 

    foreach my $method (@match) { 
    my($name,$match) = @$method; 

    print " - $name: ", $match->(), "\n"; 
    } 
} 

Beachten Sie in der Ausgabe, die mit der Zeichenfolge wie besehen falsche Treffer erzeugen kann:

 
$ ./try 
$_ = 'www.abc.com': 
    - as_is: MATCH 
    - qmeta: MATCH 
    - qe: MATCH 
$_ = 'www/abc!com': 
    - as_is: MATCH 
    - qmeta: NO MATCH 
    - qe: NO MATCH 

Für Programme, die nicht vertrauenswürdige Eingaben akzeptieren, seien Sie extrem vorsichtig bei der Verwendung solcher potenziell ekligen Bits wie reguläre Ausdrücke: Dies könnte unerwartete Laufzeitfehler, Denial-of-Se, verursachen Sicherheitslücken und Sicherheitslücken.

+0

Perfekt! Danke gbacon! – James

+0

Gern geschehen! Ich bin froh, dass es hilft. –

+0

Netter Code Greg! –

12

Der beste Weg, dies zu tun ist, \Q zu verwenden, um eine Zeichenfolge in Anführungszeichen zu beginnen und \E, um es zu beenden.

my $foo = 'www.abc.com'; 
$bar =~ /blah\Q$foo\Eblah/; 

Sie können auch zuerst quotemeta für die Variable verwenden. Z.B.

my $quoted_foo = quotemeta($foo); 

Der \Q Trick ist in perlre unter dokumentiert "Escape-Sequenzen."

Verwandte Themen