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

时间:2011-03-23 19:36:19

标签: regex perl

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

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

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

5 个答案:

答案 0 :(得分:11)

尝试这样的事情:

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

将打印:

stop  here!

一个简短的解释:

\[            # 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 ']'

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

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

修改

正如@ridgerunner所提到的,通过使*和字符类[^\[\]]匹配一次或多次使其成为{{3},您可以更有效地制作正则表达式},甚至从第1组制作possessive

\[(?:[^\[\]]++|(?0))*+]

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

答案 1 :(得分:5)

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

葛丽泰:

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

PCRE

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

请参阅“递归模式”,其中有一个括号示例。

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

\[(?R)*\]

编辑:

由于您添加了使用Perl,这里有一个明确描述如何在Perl中匹配平衡运算符对的页面:

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

类似的东西:

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

答案 2 :(得分:4)

由于您使用的是Perl,因此可以使用CPAN中的模块,而不必编写自己的正则表达式。查看允许您从平衡分隔符中提取文本的Text::Balanced模块。使用此模块意味着如果您的分隔符突然变为{},则无需弄清楚如何修改多毛的正则表达式,您只需在一个函数调用中更改分隔符参数。

答案 3 :(得分:3)

如果您只关心删除内容而不是捕获它们以便在其他地方使用,您可以使用从嵌套组内部重复删除到外部。

my $string = "stops [chomping [too] early]!";
# remove any [...] sequence that doesn't contain a [...] inside it
# and keep doing it until there are no [...] sequences to remove
1 while $string =~ s/\[[^\[\]]*\]//g; 
print $string;

条件为真时1 while基本上什么也不做。如果s///匹配并删除括号中的部分,则重复循环并再次运行s///

即使您在Bart Kiers的回答中使用旧版本的Perl或其他不支持(?0)递归扩展模式的语言,这也会有效。

答案 4 :(得分:1)

你想只删除不是[] s本身的[]之间的东西。 IE:

\[[^\]]*\]

这是一个非常多毛的[] s; - )

虽然它不会处理多个嵌套的[]。 IE,匹配[foo [bar] baz]将不起作用。