Есть ли функция Perl, чтобы превратить строку в regexp, чтобы использовать эту строку в качестве шаблона?

У меня есть проблема с использованием Perl grep() со строкой, которая может содержать символы, которые интерпретируются как кванторы регулярных выражений.

Я получил следующую ошибку, когда grep-шаблон "g++", потому что символы "+" интерпретируются как кванторы. Ниже приведен вывод для следующей программы:

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.

Есть ли модификатор, который я мог бы использовать для указания grep, что кванторы должны игнорироваться, или есть функция, которая могла бы избежать кванторов?

#! /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: в дополнение к вопросу ответа выше, я приветствую любые отзывы об использовании Perl в приведенном выше примере, поскольку я все еще участвую. Благодаря

Ответ 1

Стандартный способ - использовать индикатор \Q escape перед вашей переменной, чтобы сообщить Perl не анализировать содержимое как регулярное выражение:

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

Изменение этой строки в вашем коде дает:

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

Ответ 2

Я думаю, что вы ищете quotemeta

Ответ 3

в дополнение к вопросу ответа выше, я приветствую любые отзывы об использовании Perl в приведенном выше примере, поскольку я все еще участвую. Благодаря

Я бы посоветовал вам не использовать прототипы (($) после test_grep). У них есть свое применение, но не для большинства случаев и, безусловно, не в этом.

Ответ 4

PS: в дополнение к вопросу ответа выше, я приветствую любые отзывы о Perl использование в выше, поскольку я все еще обучение.

Лучший совет, который я могу дать для рекомендаций по кодированию Perl, - это установить Perl::Critic и использовать perlcritic в вашем коде. Если вы не можете этого сделать, вы можете использовать инструмент Perl Best Practices, поскольку Perl::Critic уже прочитал книгу и предоставит вам ссылки на страницу номера, однако, даже если у вас нет книги вокруг, вы все равно можете найти расширенную обратную связь в разделах Perl:: Critic, начиная с Perl::Critic::Policy::.

Ответ 5

Я бы предложил использовать qr для создания объектов Regexp, а не строк в этом случае.

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");

Тогда вам не нужно бежать \Q. Хотя вы все еще можете использовать его:

ok(test_grep(qr/\Qg++/), "grep, pattern found");