Почему делает мой Perl regex, жалуются на “Несопоставленный) в regex”?

if($title =~ s/(\s|^|,|\/|;|\|)$replace(\s|$|,|\/|;|\|)//ig)

$title может быть рядом заголовков в пределах от президента, Мэриленд, COO, генерального директора...

$replace может быть (акционер), (Владелец) и т.п.

Я продолжаю получать эту ошибку. Я проверил на неправильно сбалансированный' (', ')', провал :(

Unmatched ) in regex; marked by <-- HERE in m/(\s|^|,|/|;|\|)Owner) <-- HERE (\s|$|,|/|;|\|)/

Если Вы могли бы сказать мне, что делает regex, который был бы потрясающим. Это разделяет те символы?Спасибо, ребята!

9
задан toolic 16 March 2010 в 23:39
поделиться

3 ответа

Если переменная $ replace может содержать метасимволы регулярного выражения, вы должны заключить ее в \ Q ... \ E

\Q$replace\E

Процитировать Джеффри Фридла Освоение регулярных выражений

Диапазон буквального текста Последовательность \ Q «Цитаты» метасимволы регулярного выражения (т.е. ставит перед ними обратную косую черту) до конца строки или до последовательности \ E .

15
ответ дан 4 December 2019 в 09:12
поделиться

Как уже говорилось, он удалит эти знаки препинания, затем содержимое $replace, затем еще знаки препинания, и что он терпит неудачу, потому что $replace сам содержит несовпадающую скобку.

Однако, несколько других общих моментов, связанных с regex: во-первых, вместо OR (и это только для упрощения логики и набора текста) я бы хранил их вместе в классе символов. Соответствие [\s^,\/;\|] потенциально менее подвержено ошибкам и удобно для пальцев.

Во-вторых, не используйте группирующую скобку набор (), если только вы действительно не имеете в виду это. Это помещает захваченную строку в буферы захвата и создает накладные расходы в механизме regex. Согласно perldoc perlre:

ПРЕДУПРЕЖДЕНИЕ: Как только Perl видит, что вам нужно одно из $&, $`, или $' в любом месте программы, он должен предоставить их для каждого совпадения шаблона. Это может существенно замедлить работу вашей программы. Perl использует тот же механизм для получения $1, $2 и т.д., поэтому вы также платите цену за каждый шаблон, содержащий круглые скобки. Источник

Вы можете легко обойти это, просто изменив его, добавив к скобкам (?:):

(?:[\s^,\/;\|])

Редактирование: не то чтобы вам нужна группировка без захвата в этом случае, но она уже есть в оригинальном regex.

5
ответ дан 4 December 2019 в 09:12
поделиться

Похоже, что ваша переменная $ replace содержит строку Owner) , не (Владелец) .


$title = "Foo Owner Bar";
$replace = "Owner)";
if($title =~ s/(\s|^|,|\/|;|\|)$replace(\s|$|,|\/|;|\|)//ig) {
    print $title;
}

Вывод:

Unmatched ) in regex; marked by <-- HERE in m/(\s|^|,|/|;|\|)Owner)<-- HERE (\s
|$|,|/|;|\|)/ at test.pl line 3.

$title = "Foo Owner Bar";
$replace = "(Owner)";
if($title =~ s/(\s|^|,|\/|;|\|)$replace(\s|$|,|\/|;|\|)//ig) {
    print $title;
}

Вывод:

FooBar
3
ответ дан 4 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: