Perl删除()字符内的文本

时间:2016-03-16 17:27:56

标签: regex perl

我有一个变量,可能包含也可能不包含括号内的文本,例如

blah blah (soups up)

我想删除括号内的任何内容,因此对于此示例,我将留下:

blah blah

我尝试了以下替换,但它没有按预期工作:

$desc =~ s/(.*?)//gs;
print "fixed desc: $desc\n";

打印:

fixed desc:

根据讨论,任何内容,包括括号内的子括号都应该闪现

e.g。

blah blah (soups up (tomato!) )

2 个答案:

答案 0 :(得分:4)

匹配平衡文本是一个经典的硬正则表达式问题。例如,您如何处理keep (remove) keep (remove)?幸运的是,它变得更加容易。 perlfaq4 covers it。你有两个选择。

首先使用5.10中引入的递归正则表达式。 (?R)说要解决整个模式。

m{
    \(                        # Open paren
       (?>
           [^()]   |          # No nested parens OR
           (?R)               # Recurse to check for balanced parens
       )*
    \)                        # Close paren
 }x;

但是,这并不涉及像(this is \) all in parens)这样的转义。

不要进入处理转义所必需的正则表达式扭曲,而是使用模块为您构建该正则表达式。 Regexp::Common::balancedRegexp::Common::delimited可以做到这一点,以及许多其他硬性正则表达式问题,它将处理转义。

use v5.10;
use strict;
use warnings;
use Regexp::Common;

my $re = $RE{balanced}{-parens=>"()"};

my $s = "blah blah (soups up (tomato!\) )";

$s =~ s{$re}{};

say $s;    # "blah blah"

答案 1 :(得分:0)

在最简单的情况下,首先要注意的是,如果您还不担心上面提到的一些边缘情况,那么括号字符也会用于正则表达式中的分组和反向引用。因此,您需要在匹配语句中将其转义为:

  

$ desc = ~s /\(.*\)//gs;

以下是有关该主题的更多信息: http://perlmeme.org/faqs/regexp/metachar_regexp.html

第二个问题:你打算在比赛中对问号做什么? ' *'将匹配前一个字符的0-n次出现,所以我不确定'?'这里会做很多事情。