2010-03-16 99 views
8
if($title =~ s/(\s|^|,|\/|;|\|)$replace(\s|$|,|\/|;|\|)//ig) 

$标题可以是一组标题,从总裁,医学博士,首席运营官,首席执行官的...为什么我的Perl正则表达式在“正则表达式”中抱怨“不匹配”)?

$替换即可(股东),(业主)等。

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

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

如果你能告诉我,正则表达式做什么,这将是真棒,这是否剥夺这些符号?谢谢你们!

+0

如果您在$ replace中具有元字符,则应使用\ Q或quotemeta来考虑将字符视为普通字符 – sganesh 2010-03-17 04:48:51

+0

http://stackoverflow.com/questions/576435/how-do-i-handle-special-字符在perl-regex – daxim 2011-03-25 14:31:40

回答

14

如果变量$更换可以包含正则表达式元字符,你应该把它包在\Q...\E

\Q$replace\E 

引述杰弗里Friedl的掌握正表达式

文字文本跨度序列\ Q“行情” 正则表达式元字符(即,把一个反斜杠在他们面前),直到字符串的末尾,或者直到。\ E序列。

+0

短而甜!它完成了这项工作。你能否详细说明\ Q和\ E? – ThinkCode 2010-03-17 14:18:29

+0

添加了一个简短的解释。 – 2010-03-17 19:32:07

3

看来,您的变量$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 
5

如上所述,它会去掉那些标点符号,接着是$ replace的内容,然后是更多的标点符号,并且它失败了,因为$ replace本身包含不匹配的括号。但是,其他一些普通的正则表达式事情:首先,不是将所有东西放在一起(这只是为了简化逻辑和打字),而是将它们放在一个字符类中。匹配[\s^,\/;\|]可能不太容易出错并且手指友好。

二,不要使用分组圆括号一组(),除非你真的是这个意思。这将捕获的字符串放入捕获缓冲区,并在正则表达式引擎中产生开销。每perldoc perlre

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

您可以轻松地通过添加?:的括号解决这个问题只需更改它:

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

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

+0

+1,但我认为'^'和'$'是作为锚定的,所以它们不能进入字符类。这意味着groups *有必要:'(?:^ | [\ s,; | \ /])','(?:[\ s,; | \ /] | $)' – 2010-03-17 02:10:27

+0

学到了新东西。 \ Q $替换\ E解决了这个问题,但非常感谢Marc。 – ThinkCode 2010-03-17 14:19:01