<p>这涉及到处理匹配分隔符(可能是嵌套分隔符)的棘手问题</p>
<p>我建议使用core<a href="https://perldoc.perl.org/Text::Balanced" rel="nofollow noreferrer">Text::Balanced</a>来解析所有平衡(顶级)括号之外的文本字符串,而不是纠缠一个大正则表达式,这正是问题中所描述的</p>
<pre><code>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;
</code></pre>
<p>我们要求找到任何给定括号的第一个顶级对的内容,<sup>†</sup>,同时我们得到该对(<code>$remainder</code>)后面的内容和之前的内容</p>
<p>这里需要的是<code>$before</code>,我们一直以同样的方式解析<code>$remainder</code>,挑选<code>$before</code>,直到没有更多的匹配;此时<code>$remainder</code>中没有括号,因此我们也接受它(此时<code>$before</code>也必须为空)</p>
<p>代码获得预期的字符串,带有一些额外的空白;根据需要修剪</p>
<p>有关另一个示例以及使用<a href="https://metacpan.org/pod/release/ABIGAIL/Regexp-Common-2017060201/lib/Regexp/Common.pm" rel="nofollow noreferrer">Regexp::Common</a>的另一种方法,请参见<a href="https://stackoverflow.com/a/46121634/4653379">this post</a></p>
<hr/>
<p><sup>†</sup>The<code>extract_bracketed</code>提取第一个顶级平衡括号对中的内容,默认情况下需要在字符串开头(可能的空格之后)或上一个匹配结束后找到该括号;或者,在第三个参数中的模式(如果给定)之后,必须找到<em>(因此这里的<code>*</code>量词,如果括号<em>在开头是</em>)</p>
<p>因此,在本例中,它跳到第一个开口括号,<em>然后</em>解析字符串以查找平衡括号对。第二个参数给出了要查找的括号类型</p>