使用Perl自动化形态标记

RGP*_*RGP 5 regex perl

让我们假设我有一个带有形态标签的文本,以及一个没有标签的类似文本.两种文本以行间方式合并,一行低于另一行.因此(为清楚起见,增加了额外的回车):

(艺术)日(N)开始(V)井(Adv),刮风(Adj)和(C)潮湿(Adj),这里(Adv)在(P)伦敦(PN),

这一天在伦敦风很大,很潮湿,

但是(P)我们(Pr)做了(AuxV)没有(Adv)介意(V),因为(P)我们(Pr)有(AuxV)计划(V)到(P)呆(V)室内(Adv)

但没问题,伙计!我们原计划留在家里!

第二行(即未标记的文本)始终以空格和制表符开头.

此外,可以安全地忽略标点符号和区分大小写.此外,可能是第一行中的某些单词未被标记的情况.

所以,从这种伪代码开始,鉴于我对Perl的了解有限,我决定构建一系列正则表达式来提取第1行的标签(总是在括号中)并将它们插入第2行,前提是言语是一样的.

我当前的代码如下所示:

use strict;
use warnings;

while ( <DATA> )
{
s/(^\w+)(\(\w+\))?(.+\r)(\s\t)(\1)/$1$2$3$4$5$2/g; #Tag 1st word on line 2 (if it's the same one as the 1st on line 1).
s/(^\w+)(\(\w+\))?\s(\w+)(\(\w+\))?(.+\r)(\s\t)(\1\2)\s(\3)/$1$2 $3$4$5$6$7 $8$4/g; #Tag 2nd word on line 2 (if it's the same one as the 2nd on line 1).
# And so on...

print;
}


__DATA__
The(Art) day(N) started(V) well(Adv), windy(Adj) and(C) humid(Adj), here(Adv) in(P) London(PN),
    The day was windy and quite humid here in London, 
but(P) we(Pr) did(AuxV) not(Adv) mind(V), because(P) we(Pr) had(AuxV) planned(V) to(P) stay(V) indoors(Adv) 
   but no problem at all, mate! We had planned to stay at home anyway! 
Run Code Online (Sandbox Code Playgroud)

显然,我想要的输出看起来如下:

(艺术)日(N)开始(V)井(Adv),刮风(Adj)和(C)潮湿(Adj),这里(Adv)在(P)伦敦(PN),(艺术)日(N) (P)伦敦(PN),风很潮湿(调整)这里(Adv),

但是(P)我们(Pr)做了(AV)没有(高级)头脑(V),因为(P)我们(Pr)有(AuxV)计划(V)到(P)留在(V)室内(Adv)

但是(P)没问题,伙计!无论如何,我们(Pr)有(AuxV)计划(V)到(P)呆在家里(V)!


我的问题是双重的:

a)上面的脚本(目前我试图替换第一个和第二个单词)不起作用,虽然我认为正则表达式是正常的(我已经在BBEdit中测试它们作为搜索/替换).

b)我完全不确定这是解决手头任务的正确方法(即,添加一系列越来越长且更复杂的正则表达式).

有人可以告诉我应该做些什么才能让它发挥作用,或者,让我看一个更好的方法来优化任务?我全都耳朵!

非常感谢你.

tri*_*eee 3

像这样的东西吗?

#!/usr/bin/perl

use strict;
use warnings;

my %tag;

while (<DATA>)
{
    if (m/\((Adj|Art|AuxV|C|N|PN|V)\)/) # it's an example
    {
        # Loop over tagged words; memorize tag for each
        while (m/(\w+)\((\w+)\)/g)
        {
            # If there were already some tags, add to existing
            $tag{$1} = (defined $tag{$1} ? "$tag{$1}|" : "") . $2;
        }
        print;
        next;
    }
    # else
    # Loop over all words; tag the ones we have a tag for
    s/(\w+)/defined $tag{$1} ? "$1($tag{$1})" : $1 /eg;
    print;

    # Flush tags for next iteration
    %tag = ();
}
Run Code Online (Sandbox Code Playgroud)

请注意,在未标记的行之前支持多个示例行;以及对一个单词的多个标签的支持。