gpt4 book ai didi

regex - 如何使用正则表达式(在 Perl 或 *nix 终端中)匹配庞大语料库中列表中的单词?

转载 作者:行者123 更新时间:2023-12-01 01:05:44 28 4
gpt4 key购买 nike

来自 .txt 文件中的给定名词列表,其中名词用新行分隔,例如:

hooligan
football
brother
bollocks

...以及一个单独的 .txt 文件,其中包含一系列由换行符分隔的正则表达式,如下所示:
[a-z]+\tNN(S)?
[a-z]+\tJJ(S)?

...我想通过语料库的每个句子运行正则表达式,并且每次正则表达式匹配一个模式时,如果该模式包含名词列表中的一个名词,我想在输出和(用制表符分隔)匹配它的正则表达式。以下是结果输出的示例:
football    [a-z]+NN(S)?\'s POS[a-z]+NN(S)?
hooligan [a-z]+NN(S)?,,[a-z]+JJ[a-z]+NN(S)?
hooligan [a-z]+NN(S)?,,[a-z]+JJ[a-z]+NN(S)?
football [a-z]+NN(S)?[a-z]+NN(S)?
brother [a-z]+PP$[a-z]+NN(S)?
bollocks [a-z]+DT[a-z]+NN(S)?
football [a-z]+NN(s)?(be)VBZnotRB

我将使用的语料库很大(数十 GB)并且具有以下格式(每个句子都包含在标签 <s> 中):
<s>
Hooligans hooligan NNS 1 4 NMOD
, , , 2 4 P
unbridled unbridled JJ 3 4 NMOD
passion passion NN 4 0 ROOT
- - : 5 4 P
and and CC 6 4 CC
no no DT 7 9 NMOD
executive executive JJ 8 9 NMOD
boxes box NNS 9 4 COORD
. . SENT 10 0 ROOT
</s>
<s>
Hooligans hooligan NNS 1 4 NMOD
, , , 2 4 P
unbridled unbridled JJ 3 4 NMOD
passion passion NN 4 0 ROOT
- - : 5 4 P
and and CC 6 4 CC
no no DT 7 9 NMOD
executive executive JJ 8 9 NMOD
boxes box NNS 9 4 COORD
. . SENT 10 0 ROOT
</s>
<s>
Portsmouth Portsmouth NP 1 2 SBJ
bring bring VVP 2 0 ROOT
something something NN 3 2 OBJ
entirely entirely RB 4 5 AMOD
different different JJ 5 3 NMOD
to to TO 6 5 AMOD
the the DT 7 12 NMOD
Premiership Premiership NP 8 12 NMOD
: : : 9 12 P
football football NN 10 12 NMOD
's 's POS 11 10 NMOD
past past NN 12 6 PMOD
. . SENT 13 2 P
</s>
<s>
This this DT 1 2 SBJ
is be VBZ 2 0 ROOT
one one CD 3 2 PRD
of of IN 4 3 NMOD
Britain Britain NP 5 10 NMOD
's 's POS 6 5 NMOD
most most RBS 7 8 AMOD
ardent ardent JJ 8 10 NMOD
football football NN 9 10 NMOD
cities city NNS 10 4 PMOD
: : : 11 2 P
think think VVP 12 2 COORD
Liverpool Liverpool NP 13 0 ROOT
or or CC 14 13 CC
Newcastle Newcastle NP 15 19 SBJ
in in IN 16 15 ADV
miniature miniature NN 17 16 PMOD
, , , 18 15 P
wound wind VVD 19 13 COORD
back back RB 20 19 ADV
three three CD 21 22 NMOD
decades decade NNS 22 19 OBJ
. . SENT 23 2 P
</s>

我开始在 PERL 中编写一个脚本来实现我的目标,为了不让如此庞大的数据集耗尽内存,我使用了模块 Tie::File这样我的脚本将一次读取一行(而不是尝试打开内存中的整个语料库文件)。这将与每个句子对应一行的语料库完美配合,但在当前句子分布在更多行上并由标签分隔的情况下则不行。

有没有办法使用组合 unix 终端命令(例如 cat 和 grep)来实现我想要的?或者,这将是这个问题的最佳解决方案? (一些代码示例会很棒)。

最佳答案

一个简单的正则表达式替换就足以从名词列表和 Regexp::Assemble 中提取匹配数据。可以处理识别来自其​​他文件的哪个模式匹配的要求。而且,正如 Jonathan Leffler 在他的评论中提到的那样,设置输入记录分隔符允许您一次读取一条记录,即使每条记录跨越多行。

将所有这些结合到一个运行示例中,我们得到:

#!/usr/bin/env perl    

use strict;
use warnings;
use 5.010;

use Regexp::Assemble;

my @nouns = qw( hooligan football brother bollocks );
my @patterns = ('[a-z]+\s+NN(S)?', '[a-z]+\s+JJ(S)?');

my $name_re = '(' . join('|', @nouns) . ')'; # Assumes no regex metacharacters

my $ra = Regexp::Assemble->new(track => 1);
$ra->add(@patterns);

local $/ = '<s>';

while (my $line = <DATA>) {
my $match = $ra->match($line);
next unless defined $match;

while ($line =~ /$name_re/g) {
say "$1\t\t$match";
}
}


__DATA__
...

... __DATA__ 的内容在哪里section 是原始问题中提供的样本语料库。为了保持答案紧凑,我没有在此处包含它。另请注意,在这两种模式中,我都更改了 \t\s+ ;这是因为当我复制和粘贴您的样本语料库时,这些选项卡没有保留。

运行该代码,我得到输出:
hooligan        [a-z]+\s+NN(S)?
hooligan [a-z]+\s+NN(S)?
football [a-z]+\s+NN(S)?
football [a-z]+\s+NN(S)?
football [a-z]+\s+JJ(S)?
football [a-z]+\s+JJ(S)?

编辑:更正了正则表达式。我最初更换了 \t\s ,使其匹配 NNJJ仅当前面正好有一个空格时。它现在还匹配多个空格,更好地模拟原始 \t .

关于regex - 如何使用正则表达式(在 Perl 或 *nix 终端中)匹配庞大语料库中列表中的单词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18884296/

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