Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用制表符/空格分隔输出:Perl_Perl_Pattern Matching - Fatal编程技术网

用制表符/空格分隔输出:Perl

用制表符/空格分隔输出:Perl,perl,pattern-matching,Perl,Pattern Matching,我正在处理三个文本文档。第一个是主输入(输入1),单词和单词类型(名词、动词等)由制表符分隔 输入1 John N goes V to P school N . S Mary N comes V from P home N . S 第二个和第三个输入文本文件如下所示: 输入2 John Mary 投入3 to from 我的目标是将第二个和第三个文本文件与主输入进行比较和匹配,并获得如下输出: John N N go

我正在处理三个文本文档。第一个是主输入(输入1),单词和单词类型(名词、动词等)由制表符分隔

输入1

John    N
goes    V
to      P
school  N
.       S
Mary    N
comes   V
from    P
home    N
.       S
第二个和第三个输入文本文件如下所示:

输入2

John
Mary
投入3

to
from
我的目标是将第二个和第三个文本文件与主输入进行比较和匹配,并获得如下输出:

John N  
N
goes    
V
to P    
P
school  
N
.   
S
Mary N  
N
comes   
V
from P  
P
home    
N
.   
S
预期产出:

John    N   N
goes    V
to      P   P
school  N
.       S
Mary    N   N
comes   V
from    P   P
home    N
.       S
因此,基本上,所有三列都应该用制表符或空格分隔。但是,我得到的输出如下:

John N  
N
goes    
V
to P    
P
school  
N
.   
S
Mary N  
N
comes   
V
from P  
P
home    
N
.   
S
我相信这是在我将第一个文本文件的输入放入数组并打印值时发生的。请建议一种获得所需输出的方法。 我使用的程序编码如下:

#!/usr/bin/perl

use warnings;
use strict;

my @file = ('Input 1.txt');

open my $word_fh, '<', 'Input 2.txt' or die $!;
open my $word2_fh, '<', 'Input 3.txt' or die $!;

my %words_to_match = map {chomp $_; $_ => 0} <$word_fh>;
my %words_to_match2 = map {chomp $_; $_ => 0} <$word2_fh>;

close $word_fh;
close $word2_fh;

check($_) for @file;

sub check {
    my $file = shift;

open my $fh, '<', $file or die $!;

while (<$fh>){
    chomp;
    my @words_in_line = split;

    for my $word (@words_in_line){
        $word =~ s/[(\.,;:!)]//g;
        $word .= '  N' if exists $words_to_match{$word};
        $word .= '  P' if exists $words_to_match2{$word};

        print "$word\n";
    }
    print "\n";
}
#/usr/bin/perl
使用警告;
严格使用;
my@file=('Input 1.txt');

打开我的$word_fh,“您正在输出一个不必要的换行符,并且您正在错误地构造新的输出行。不需要在哈希表中搜索“type”列。这将产生所需的输出

use warnings;
use strict;

my @file = ('Input 1.txt');

open my $word_fh,  '<', 'Input 2.txt' or die $!;
open my $word2_fh, '<', 'Input 3.txt' or die $!;

my %words_to_match  = map { chomp $_; $_ => 0 } <$word_fh>;
my %words_to_match2 = map { chomp $_; $_ => 0 } <$word2_fh>;

close $word_fh;
close $word2_fh;

check($_) for @file;

sub check {
    my $file = shift;
    open my $fh, '<', $file or die $!;
    while (<$fh>) {
        chomp;
        my ($word, $type) = split;
        my $line = $_;
        $line .= '  N' if exists $words_to_match{$word};
        $line .= '  P' if exists $words_to_match2{$word};
        print "$line\n";
    }
}
使用警告;
严格使用;
my@file=('Input 1.txt');
打开我的$word\u fh,“问题是:

my @words_in_line = split;

for my $word (@words_in_line){
    ...
}
您要做的是查看行中的第一个单词,查看它是否匹配任何
%words\u to_match
变量,如果匹配,则将
N
p
附加到整行

现在你看到的是一行中的每个词,而不是第一个词。然后将
N
P
附加到单词本身,而不是整行

以下是正确的伪代码:

# get the first word in the line
# if it matches `%words_to_match` then append the `  N` to the entire line
# if it matches `%words_to_match2` then append the `  P` to the entire line
# print the line
我从答案的第一段中得到了这个伪代码,并把它分解成了碎片

无论如何,在Perl中,它看起来是这样的:

my ($first_word) = split;

$_ .= '  N' if exists $words_to_match{$first_word};
$_ .= '  P' if exists $words_to_match2{$first_word};

print "$_\n";

如果您先读取所有参考文件并从中构建数据结构,然后读取主输入文件并对其进行转换,那么事情就会变得容易得多

您正在使用两个散列,
%words\u to\u match
%words\u to\u match2
,并以零值存储每个元素。这是对信息的浪费,最好的办法是构建一个散列,将每个引用文件中的单词与其词性关联起来。
Input 2.txt
中的单词是名词,因此它们得到一个
N
,而
Input 3.txt
中的单词是介词,因此它们得到一个
P

然后,您只需检查是否存在与
Input 1.txt
中的每个单词匹配的哈希元素,并在打印记录之前附加其值(如果存在)

下面的程序创建一个如下所示的哈希
%pos
,它将两个参考文件中的每个单词与其词性关联起来

(from=>“P”,John=>“N”,Mary=>“N”,to=>“P”)
在最后的输入循环中,我使用了一个子替换
s//
,用三个空格和词性替换所有尾随空格(包括换行符)。制表符在布局表时并不是有用的东西,首先是因为没有人能同意制表符的停止位置,其次是因为单个制表符并不总是排列列。根据前面数据中的字符数,有时可能需要两个或更多字符

我希望它是清楚的

使用严格;
使用“全部”警告;
使用自动模具;
我的%字;
我的%files=(
'input 2.txt'=>'N',
'input 3.txt'=>'P',
);
而(我的($file,$pos)=每个%files){
打开我的$fh,'