Как сопоставить '(' с помощью регулярных выражений? - PullRequest
2 голосов
/ 20 марта 2012

Когда я делаю это

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my $s = 'dfgdfg5 )';
my $a = '5 )';
my $b = '567';

$s =~ s/$a/$b/g;
print Dumper $s;

Я получаю

Unmatched ) in regex; marked by <-- HERE in m/5 ) <-- HERE / at ./test.pl line 11.

Проблема в том, что $a имеет (.

Как предотвратить сбои регулярного выражения?

Обновление

Строка в $a я получаю из запроса к базе данных, поэтому я не могу ее изменить. Или можно было бы создать $a2, где «что-то» ищет ) и заменяет их на \)?

Ответы [ 6 ]

11 голосов
/ 20 марта 2012

Вы должны избежать этого. Либо вручную, добавив обратную косую черту перед ним, либо используя quotemeta или \Q sequence внутри регулярного выражения:

$a = quotemeta($a);

Или

$s =~ /\Q$a/$b/g;

ETA: Это хороший вариант, если вы хотите сопоставить литеральные строки из запроса к базе данных.

Вы также должны знать, что не стоит использовать $a и $b в качестве переменных, поскольку они будут маскировать предопределенные переменные, которые используются с sort. Например. sort { $a <=> $b } @foo.

4 голосов
/ 20 марта 2012

Простой ответ - убежать от парена. my $a = '5 \)'; В вашем случае, как упоминается в вашем посте, вы не тот, кто создает строки, поэтому буквально экранировать их не вариант.

Может быть проще обернуть переменную, которая интерполируется регулярным выражением внутри \ Q ... \ E.

$s =~ s/\Q$a\E/$b/g;

Функция quotemeta() также может быть полезна для вас, в зависимости от того, как ваш код учтен. С этой опцией вы передадите $ a через quotemeta перед интерполяцией в регулярное выражение. \ Q ... \ E, вероятно, проще в этой ситуации, но если ваш код упрощен с использованием взамен quotemeta, он для вас.

3 голосов
/ 20 марта 2012

Используйте \) вместо ). ) особенный, потому что обычно используется для захвата паттернов, поэтому вам нужно сначала его избежать.

2 голосов
/ 20 марта 2012

Избегайте скобок с обратной косой чертой:

my $a = '5 \)'oi;

Или используйте \ Q внутри регулярного выражения:

$s =~ s/\Q$a/$b/g;

Также при сохранении регулярных выражений в переменной, вы должны посмотреть регулярное выражениеоператор цитаты: http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators

my $a = qr/5 \)/oi;
1 голос
/ 20 марта 2012

В регулярном выражении Perl необходимо маскировать специальные символы обратной косой чертой \.

Попробуйте

my $a = '5 \)';
my $b = '567';

$s =~ s/$a/$b/g;

Подробнее и хорошее начало см. perldoc perlretut

Обновление: Я не знал, что RE пришло из базы данных.Ну, код выше работает, тем не менее.Подсказка к учебнику по-прежнему применяется.

0 голосов
/ 20 марта 2012

Я думаю, вам просто нужно убрать скобки, т.е. заменить ) на \)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...