标记字符串中的项目列表而不重叠

mark list of items in string without overlap

我有一个文本示例:

my $text = 'a bb cc xx aa a b c a';

以及文本中可能出现的术语列表:

my @words = ('bb cc',
    'a bb cc',
    'xx aa a b',
    'a b',
    'a'
);

我需要找到这些词的出现,使用尽可能长的匹配,并且不标记任何内容两次。因此,如果我在上面的文本中标记匹配项,它将如下所示:

<a bb cc> <xx aa a b> c <a>

请注意,我没有标记 bb cc,因为那是较大匹配 a bb cc.

的一部分

有什么方法可以做到这一点吗?感觉以前应该遇到过很多次了

一个简单的替换就可以了,你必须按长度排序:

my $re = '('.join('|', sort {length $b <=> length $a} map(quotemeta,@words)).')';
$text =~ s/$re/<>/g;
say $text;

5.20.2 的输出符合预期,现在无法检查其他版本。 您提供的示例实际上不需要 quotemeta 部分,它用于转义正则表达式中具有特殊含义的字符。