正则表达式:删除方括号的内容

ajw*_*ood 2 regex perl

是否有正则表达式可用于搜索/替换以删除方括号(和括号)中发生的所有内容?

我试过\[.*\]扼杀额外的东西(例如"[chomps] extra [stuff]")

此外,\[.*?\]当存在嵌套括号时,与惰性匹配相同的操作也不起作用(例如"stops [chomping [too] early]!")

Bar*_*ers 11

尝试这样的事情:

$text = "stop [chomping [too] early] here!";
$text =~ s/\[([^\[\]]|(?0))*]//g;
print($text);
Run Code Online (Sandbox Code Playgroud)

将打印:

stop  here!
Run Code Online (Sandbox Code Playgroud)

一个简短的解释:

\[            # match '['
(             # start group 1
  [^\[\]]     #   match any char except '[' and ']'
  |           #   OR
  (?0)        #   recursively match group 0 (the entire pattern!)
)*            # end group 1 and repeat it zero or more times
]             # match ']'
Run Code Online (Sandbox Code Playgroud)

上面的正则表达式将替换为空字符串.

您可以在线测试:http://ideone.com/tps8t

编辑

正如@ridgerunner所提到的,你可以通过使*和字符类[^\[\]]匹配一次或多次并使其具有占有性来提高正则表达式,甚至通过从第1 组创建非捕获组:

\[(?:[^\[\]]++|(?0))*+]
Run Code Online (Sandbox Code Playgroud)

但是,当使用大字符串时,速度的真正提高可能是显而易见的(当然,你可以测试它!).

  • +1通过在第一个替代项中添加所有权加法,可以使这个表达式更有效:`\ [([^\[\ _]] ++ |(?0))*]` (2认同)

Tim*_*ter 5

对于正则表达式,这在技术上是不可能的,因为您匹配的语言不符合"常规"的定义.有一些扩展的正则表达式实现,无论如何都可以使用递归表达式,其中包括:

格里塔:

http://easyethical.org/opensource/spider/regexp%20c++/greta2.htm#_Toc39890907

和

PCRE

http://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions

请参阅"递归模式",其中有一个括号示例.

PCRE递归括号匹配将如下所示:

\[(?R)*\]
Run Code Online (Sandbox Code Playgroud)

编辑:

既然您已经添加了Perl,那么这里是一个明确描述如何在Perl中匹配平衡运算符对的页面:

http://perldoc.perl.org/perlfaq6.html#Can-I-use-Perl-regular-expressions-to-match-balanced-text%3f

就像是:

$string =~ m/(\[(?:[^\[\]]++|(?1))*\])/xg;
Run Code Online (Sandbox Code Playgroud)