Почему мой Perl regex жалуется на "Unmatched) в regex"? - PullRequest
9 голосов
/ 17 марта 2010
if($title =~ s/(\s|^|,|\/|;|\|)$replace(\s|$|,|\/|;|\|)//ig)

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

$ заменить можно (акционер), (владелец) или тому подобное.

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

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

Если бы вы могли сказать мне, что делает регулярное выражение, это было бы замечательно. Это лишает эти символы? Спасибо, ребята!

Ответы [ 3 ]

15 голосов
/ 17 марта 2010

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

\Q$replace\E

Цитирую регулярные выражения мастеринга Джеффри Фридла

Литеральный текстовый интервал Последовательность \ Q"Кавычки" регулярное выражение метасимволы (т. Е. Ставит перед ними обратную косую черту) до конца строки или до последовательности \ E .

5 голосов
/ 17 марта 2010

Как уже упоминалось, эти символы пунктуации будут удалены, за ними следует содержимое символа $ replace, затем больше символов пунктуации, а также сбой, поскольку сам $ replace содержит несоответствующие скобки.

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

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

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

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

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

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

3 голосов
/ 17 марта 2010

Похоже, что ваша переменная $replace содержит строку Owner), а не (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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...