gpt4 book ai didi

regex - Perl 正则表达式/替换嵌套短语

转载 作者:行者123 更新时间:2023-12-04 18:14:52 25 4
gpt4 key购买 nike

我有一个 perl 脚本,它逐行处理文本文件并将这些行中的短语转换为链接(特别是在 mediawiki 标记中,但我怀疑任何标记都会有同样的问题)。当一个短语是另一个短语的子集时,我会陷入困境。在这些情况下,会创建太多链接。

例如,如果“General Committee”和“Annual General Committee Meeting”是短语中的两个:

The General Committee meeting shall meet once a month.



正确转换为:

The [[#GC|General Committee]] meeting shall meet one a month.



然而,

The Annual General Committee Meeting shall be held in May.



被错误地转换为:

The [[#AGCM|Annual [[#GC|General Committee]] Meeting]] shall be held in May.



也就是说,我的脚本是在“年度总务委员会 session ”中找到短语“总务委员会”,并在我不想要的地方插入一个链接。在这个例子中应该只有一个到 AGCM 的链接。

相关的perl代码是:
my($line) = $_;
foreach $phrase (keys(%phrases)) # the phrases to replace mapped to their links
{
my($link) = $phrases{$phrase};
if ($line =~ m/$phrase/)
{
$line =~ s/$phrase/[[#$link|$phrase]]/g;
}
}

当可以找到一个短语与另一个短语时如何避免匹配/替换的任何建议?

更新:基于一些问题的澄清:每个短语都是独立的;没有一个优先于另一个。以最长的时间超过最短的时间就足以得到我需要的东西。

最佳答案

您应该在一次比较中构建一个匹配任何散列键的正则表达式。

这个程序显示了这个想法。键按长度递减排序,以便首先找到最长的匹配项,然后与 | 连接。交替字符作为分隔符。

然后只需找到所有出现的构建模式并将其替换为相应的哈希元素值即可。这可以在一次替换中完成,而不需要循环。

请注意,您可能需要考虑插入 map使用 \s+代替空格,也许放 \b在字符串之前和之后,以确保匹配的字符串不是较长单词的一部分。还有 /i正则表达式修饰符可能与允许与大小写无关的匹配有关。

use strict;
use warnings;

my %phrases = (
'General Committee' => '[[#GC|General Committee]]',
'Annual General Committee Meeting' => '[[#AGCM|Annual General Committee Meeting]]',
);

my $text = <<END;
The General Committee meeting shall meet once a month.
The Annual General Committee Meeting shall be held in May.
END

my $regex = join '|', sort { length $b <=> length $a } keys %phrases;

$text =~ s/($regex)/$phrases{$1}/g;

print $text, "\n";

输出
The [[#GC|General Committee]] meeting shall meet once a month.
The [[#AGCM|Annual General Committee Meeting]] shall be held in May.

关于regex - Perl 正则表达式/替换嵌套短语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11926860/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com