【问题标题】:Why does my Perl regex complain about "Unmatched ) in regex"?为什么我的 Perl regex 抱怨“Unmatched ) in regex”?
【发布时间】:2013-04-23 22:53:56
【问题描述】:
if($title =~ s/(\s|^|,|\/|;|\|)$replace(\s|$|,|\/|;|\|)//ig)

$title 可以是一组头衔,包括总裁、总经理、首席运营官、首席执行官……

$replace 可以是(股东)、(所有者)等。

我不断收到此错误。我检查了不正确的平衡'(',')',没有骰子:(

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

如果你能告诉我正则表达式的作用,那就太棒了。它会剥离那些符号吗?谢谢大家!

【问题讨论】:

标签: regex perl


【解决方案1】:

如果变量 $replace 可以包含正则表达式元字符,则应将其包装在 \Q...\E

\Q$replace\E

引用 Jeffrey Friedl 的精通正则表达式

Literal Text Span 序列 \Q “引号”regex 元字符(即在它们前面放一个反斜杠)直到结尾字符串,或者直到一个 \E 序列。

【讨论】:

  • 又短又甜!它完成了这项工作。能否请您详细说明 \Q 和 \E?
【解决方案2】:

如前所述,它会删除那些标点符号,然后是 $replace 的内容,然后是更多的标点符号,它会失败,因为 $replace 本身包含不匹配的括号。

但是,还有一些其他通用的正则表达式:首先,我将它们放在一个字符类中,而不是将所有东西放在一起(这只是为了简化逻辑和打字)。匹配 [\s^,\/;\|] 可能更不容易出错并且手指友好。

其次,除非您是认真的,否则不要使用一组() 分组括号。这会将捕获的字符串放在捕获缓冲区中,并在正则表达式引擎中产生开销。每perldoc perlre:

警告:一旦 Perl 发现您在程序中的任何位置需要 $& 、 $` 或 $' 之一,它就必须为每个模式匹配提供它们。这可能会大大减慢您的程序。 Perl 使用相同的机制来生成 $1、$2 等,因此您还要为每个包含捕获括号的模式付出代价。 Source

您可以通过在括号中添加?: 来轻松解决此问题:

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

编辑:不是您需要在该实例中进行非捕获分组,但它已经在原始正则表达式中。

【讨论】:

  • +1,但我认为^ 和$ 是作为锚点的,所以它们不能进入字符类。这意味着组是必要的:(?:^|[\s,;|\/])、(?:[\s,;|\/]|$)
  • 学到了新东西。 \Q$replace\E 解决了这个问题,但非常感谢 Marc。
【解决方案3】:

您的变量$replace 似乎包含字符串Owner),而不是(Owner)。


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

输出:

不匹配 ) 在正则表达式中;标记为
$title = "Foo Owner Bar";
$replace = "(Owner)";
if($title =~ s/(\s|^|,|\/|;|\|)$replace(\s|$|,|\/|;|\|)//ig) {
    print $title;
}

输出:

FooBar

【讨论】:

    猜你喜欢
    • 2020-07-02
    • 2021-10-25
    • 2011-01-31
    • 1970-01-01
    • 2010-10-11
    • 2011-01-31
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多