首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Perl实现形态标注的自动化

用Perl实现形态标注的自动化
EN

Stack Overflow用户
提问于 2011-08-29 11:30:51
回答 5查看 243关注 0票数 5

假设我有一个带有形态标记的文本,还有一个类似的文本,它完全没有标记。这两种文本以一种相互交织的方式合并,一条线在另一条线下。因此(为明确起见增加了额外的运输返回):

(艺术)日(N)在(P)伦敦(PN)开始了好日子(V)、刮风(Adj)和(C)潮湿(Adj)。

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

但是(P)我们(Pr)没有(AuxV)头脑(V),因为(P)我们(Pr)计划(Pr)到(P)呆在室内(V)。

但一点问题都没有伙计!我们本来打算呆在家里的!

第二行(即无标记文本)的前面总是有空格和制表符。

此外,标点符号和大小写敏感性也可以被安全地忽略.此外,第一行中的一些词可能不加标记。

因此,从这种伪代码中,并且考虑到我对Perl的了解是有限的,我决定构建一系列regexes来提取第1行的标记(总是在括号中),并将它们插入到第2行,前提是单词是相同的。

我的当前代码如下:

代码语言:javascript
复制
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! 

显然,我试图获得的输出如下:

(艺术)日(N)在(P)伦敦(PN)开始有风,有风(Adj)和(C)潮湿(Adj),(Art)日(N)在(P)伦敦(PN)有风和相当潮湿,

但是,我们(公共关系)没有意识到((P)),因为(P)我们(Pr)有(AuxV)计划((V)到(P)(V)呆在室内。)

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

我的问题有两个:

( a)上面的脚本(目前我只尝试替换第一个和第二个单词)不起作用,尽管我认为regexes是可以的(我已经在BBEdit中测试了它们作为搜索/替换)。

( b)我一点也不确定这是否是解决手头任务的正确方法(即,增加一系列越来越长、更复杂的正则表达式)。

有人能告诉我该怎么做才能让它开始工作吗?或者,告诉我一种更好的优化任务的方法?我在认真地听呢!

非常感谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-08-29 12:42:15

像这样吗?

代码语言:javascript
复制
#!/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 = ();
}

注意对多个示例行的支持,以及对一个单词的多个标记的支持。

票数 3
EN

Stack Overflow用户

发布于 2011-08-29 12:21:28

读取第一行,构建一个哈希,将单词与其相应的标记映射。逐字阅读第二行,从散列中插入匹配标记。

Regex可以简单到:

代码语言:javascript
复制
line =~ / ([A-z]+)\(([A-z]+)\)/
票数 1
EN

Stack Overflow用户

发布于 2011-08-29 12:50:47

代码语言:javascript
复制
while ( <DATA> )
{
    if (m/\(/) {
        while (m/(\w+)(\(\w+\))/g) {
            $hash{$1}=$2;
        }
    }
    elsif (m/^\s+/) {
        push(@empty,$_)
    }
}

foreach (@empty) {
    s/[.,]/ /g;
    for (split(/\W/)) {
        printf("%s%s ", $_, $hash{$_});
    }
    print "\n";
}

产出:

代码语言:javascript
复制
The(Art) day(N) was windy(Adj) and(C) quite humid(Adj) here(Adv) in(P) London(PN)  
but(P) no problem at all  mate! We had(AuxV) planned(V) to(P) stay(V) at home anyway! 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7229494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档