标记字符串中的项目列表而不重叠
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
部分,它用于转义正则表达式中具有特殊含义的字符。
我有一个文本示例:
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
部分,它用于转义正则表达式中具有特殊含义的字符。