首页 > 解决方案 > 正则表达式只匹配各种括号外的内容

问题描述

对于这个字符串:hello (hi that [is] so cool) awesome {yeah} 我希望正则表达式只匹配helloand awesome

这是我迄今为止尝试过的,它似乎不起作用。 https://regex101.com/r/NsUfQR/1

([^\(\)\[\]\{\}[]()〔〕〈〉【】]+)(?![^()\[\]\{\}[]()〔〕〈〉【】]*[\)\])〕〉】]])

这匹配hello hi that awesome yeah太多了。

是否可以仅使用正则表达式来实现这一点,或者是否有另一种使用 perl 或 python 的方法?

标签: pythonregexperl

解决方案


这涉及到处理匹配分隔符的棘手事务,可能是嵌套的。

我建议不要纠结一个盛大的正则表达式,而是使用核心Text::Balanced解析所有平衡(顶级)括号对之外的文本字符串,这正是问题中描述的内容

use warnings;
use strict;
use feature 'say';

use Text::Balanced qw(extract_bracketed);

my $string = 'hello (hi that [is] so cool) awesome {yeah}';

my @outside_of_brackets;

my ($match, $before);
my $remainder = $string;
while (1) {
    ($match, $remainder, $before) = extract_bracketed(
        $remainder, '(){}[]', '[^({[]*'
    );
    push @outside_of_brackets, $before // $remainder;
    last if not defined $match; 
}

say for @outside_of_brackets;

我们要求找到任何给定括号的第一个顶级对的内容,†</sup> 并且我们得到了对 ( $remainder) 之后的内容以及它之前的内容。

这就是$before这里需要的,我们继续$remainder以相同的方式解析,选择$before's,直到没有更多匹配项;那时,其中$remainder没有括号,所以我们也接受它(此时也$before必须为空)。

代码得到预期的字符串,带有一些额外的空格;根据需要修剪。

对于另一个示例,以及使用Regexp::Common的另一种方法,请参阅这篇文章


†</sup>extract_bracketed提取第一对顶级平衡括号中的内容,默认情况下需要在字符串的开头(可能的空格之后)或在其上一个匹配结束之后找到;或者,在第三个参数(如果给定)中的模式之后,然后必须找到它(因此*这里的量词,以防括号开头)。

所以在这种情况下,它会跳到第一个左括号,然后解析字符串以寻找平衡的括号对。要查找的括号类型作为其第二个参数给出。


推荐阅读