2009-02-23 15 views
7

Sto usando un programma Perl per estrarre il testo da un file. Ho un array di stringhe che uso come delimitatori per il testo, per esempio:Come si gestiscono caratteri speciali in un'espressione regolare Perl?

$pat = $arr[1] . '(.*?)' . $arr[2]; 

if ($src =~ /$pat/) { 
    print $1; 
} 

Tuttavia, due delle stringhe nella matrice sono $450 e (Buy now). Il problema con questi è che i simboli nelle string rappresentano il gruppo di fine stringa e di cattura nelle espressioni regolari di Perl, quindi il testo non analizza come intendo.

C'è un modo per aggirare questo?

risposta

11

Prova la funzione quotemeta di Perl. In alternativa, usa \Q e \E nella tua espressione regolare per disattivare l'interpolazione dei valori nella regex. Vedi perlretut per ulteriori informazioni su \Q e \E - potrebbero non essere quello che stai cercando.

+0

In particolare, \ Q non protegge dai caratteri di escape backslash. quotemeta è di gran lunga la soluzione più generale. –

+2

@BenBlank: Di cosa stai parlando? '\ Q' * compila in *' quotemeta'. Sono la stessa funzione. Allo stesso modo, '\ L' compila in' lc', '\ U' in' uc', ecc. '\ Q'" protegge contro "i caratteri di escape backslash perfettamente bene, perché ** è' \ Q' dopo tutto! ** – tchrist

4

Uso quotemeta:

$pat = quotemeta($arr[1]).'(.*?)'.quotemeta($arr[2]); 
if($src=~$pat) print $1; 
9

quotemeta sfugge meta-caratteri in modo che siano interpretati come letterali. Come scorciatoia, è possibile utilizzare \ Q ... \ E in un contesto doppio quotish a circondare roba che dovrebbe essere citato:

$pat = quotemeta($arr[1]).'(.*?)'.quotemeta($arr[2]); 
if($src=~$pat) { print $1 } 

o

$pat = "\Q$arr[1]\E(.*?)\Q$arr[2]"; # \E not necessary at the end 
if($src=~$pat) { print $1 } 

o semplicemente

if ($src =~ /\Q$arr[1]\E(.*?)\Q$arr[2]/) { print $1 } 

Si noti che questo non è limitato alle variabili interpolate; caratteri letterali sono colpite troppo:

perl -wle'print "\Q.+?"' 
\.\+\? 

anche se ovviamente accade dopo l'interpolazione variabile, in modo da "\ Q $ pippo" non diventa '\ $ pippo'.

Problemi correlati