假设我有一个带有形态标记的文本,还有一个类似的文本,它完全没有标记。这两种文本以一种相互交织的方式合并,一条线在另一条线下。因此(为明确起见增加了额外的运输返回):
(艺术)日(N)在(P)伦敦(PN)开始了好日子(V)、刮风(Adj)和(C)潮湿(Adj)。
伦敦这一天风很大,很潮湿,
但是(P)我们(Pr)没有(AuxV)头脑(V),因为(P)我们(Pr)计划(Pr)到(P)呆在室内(V)。
但一点问题都没有伙计!我们本来打算呆在家里的!
第二行(即无标记文本)的前面总是有空格和制表符。
此外,标点符号和大小写敏感性也可以被安全地忽略.此外,第一行中的一些词可能不加标记。
因此,从这种伪代码中,并且考虑到我对Perl的了解是有限的,我决定构建一系列regexes来提取第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! 显然,我试图获得的输出如下:
(艺术)日(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)我一点也不确定这是否是解决手头任务的正确方法(即,增加一系列越来越长、更复杂的正则表达式)。
有人能告诉我该怎么做才能让它开始工作吗?或者,告诉我一种更好的优化任务的方法?我在认真地听呢!
非常感谢。
发布于 2011-08-29 12:42:15
像这样吗?
#!/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 = ();
}注意对多个示例行的支持,以及对一个单词的多个标记的支持。
发布于 2011-08-29 12:21:28
读取第一行,构建一个哈希,将单词与其相应的标记映射。逐字阅读第二行,从散列中插入匹配标记。
Regex可以简单到:
line =~ / ([A-z]+)\(([A-z]+)\)/发布于 2011-08-29 12:50:47
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";
}产出:
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! https://stackoverflow.com/questions/7229494
复制相似问题