2009-12-22 20 views
13

¿Hay una forma incorporada de escapar de una cadena que se usará dentro de/como una expresión regular? P.ej.¿Cómo puedo escapar de una cadena literal que quiero interpolar en una expresión regular?

www.abc.com 

El escaparon versión sería:

www\.abc\.com 

que iba a utilizar:

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

Pero sólo quería asegurarse de que no hay un limpiador integrado de operación que ¿Estoy perdido?

+1

También respondí esto en http://stackoverflow.com/questions/1893067/how-can-i-match-in-a-regular-expression/1894320#1894320 –

+1

posible duplicado de [¿Cómo manejo los caracteres especiales? en una expresión regular de Perl?] (http://stackoverflow.com/questions/576435/how-do-i-handle-special-characters-in-a-perl-regex) – daxim

Respuesta

30

Utilice quotemeta o \Q...\E.

Consideremos el siguiente programa de prueba que coincide en contra $str que está, con quotemeta, y con \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"; 
    } 
} 

Observe en el resultado que el uso de la cadena tal cual podría producir falsas coincidencias:

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

Para programas que aceptan entradas poco confiables, tenga mucho cuidado con el uso de tales bits potencialmente desagradables como expresiones regulares: al hacerlo podría crear errores de tiempo de ejecución inesperados, denegación de se vulnerabilidades de los servicios y agujeros de seguridad.

+0

¡Perfecto! Gracias gbacon! – James

+0

¡De nada! Me alegro de que ayude. –

+0

Buen código Greg! –

12

La mejor manera de hacerlo es usar \Q para comenzar una cadena entre comillas y \E para finalizarlo.

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

También puede usar quotemeta en la variable primero. P.ej.

my $quoted_foo = quotemeta($foo); 

El truco \Q se documenta en perlre en "Secuencias de escape."

Cuestiones relacionadas