将包含2列的文本文件转换为Perl哈希
下面是我的输入文本文件将包含2列的文本文件转换为Perl哈希,perl,text,hash,Perl,Text,Hash,下面是我的输入文本文件 StudentName Address Boris Vietnam Henry Ukrine Sarah Road/47
StudentName Address
Boris Vietnam
Henry Ukrine
Sarah Road/47
Turkey
John NewsLand
now local
Boris now local
Karen 4th/floor
WestHam/Apartments
Culverdown/Street
WestHam
UK
为了将上面的内容转换成散列,我尝试了以下方法(当然它根本不起作用)
使用严格;使用警告;使用数据::转储程序;
my$out1=“Sample.txt”;我的%hash;
打开文件1,“此处的关键问题是正确跳过重复的名称。一种可能的方法:
my $name;
while ( <FILE1> ) {
chomp;
my @row = split /\s+/, $_, 2;
next if $row[0] eq 'StudentName';
$name = $row[0] unless $row[0] eq '';
push @{ $hash{$name} }, $row[1];
}
我的$name;
而{
咀嚼;
my@row=split/\s+/,$\u2;
下一个if$row[0]eq'StudentName';
$name=$row[0],除非$row[0]相等“”;
push@{$hash{$name}},$row[1];
}
这里我使用了三个参数形式的split
来限制块的数量,跳过了StudentName
行和next
,仅当行以非空白符号开头时才填充$name
请注意,由于自动激活,您不必为每个特定记录预先创建列表-推送将自动创建相应的数据结构。您遇到的问题是您的,而循环基于换行符进行迭代。在第一行中,您有一个学生姓名,但在下一行中没有
所以我建议你要做的是:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my %addresses;
my $current_student_name;
my $header_line = <>;
while (<>) {
my $address_line;
if (m/^\w/) {
( $current_student_name, $address_line ) = m/^(\w+)\s*(.*)/;
}
else {
($address_line) = m/^\s*(.*)/;
}
push( @{ $addresses{$current_student_name} }, $address_line );
}
print Dumper \%addresses;
!/usr/bin/env perl
严格使用;
使用警告;
使用数据::转储程序;
我的%地址;
我的$current\u student\u姓名;
我的$header_行=;
而(){
我的$address\u行;
如果(m/^\w/){
($current_student_name,$address_line)=m/^(\w+)\s*(.*)/;
}
否则{
($address_line)=m/^\s*(.*)/;
}
推送(@{$addresses{$current_student_name},$address_line);
}
打印转储程序\%地址;
如果我理解正确,这可能是一个解决方案
my $prev_name;
while ( <FILE1> ) {
chomp $_;
my ( $name, $address ) = split /\s+/, $_, 2;
$hash{$prev_name = $name} ||= [] if $name;
push($hash{$name || $prev_name}, $address);
}
my$prev\u name;
而{
大口大口;
我的($name,$address)=拆分/\s+/,$\u2;
$hash{$prev_name=$name}| |=[]如果$name;
push($hash{$name | |$prev_name},$address);
}
Opps.Spitting肯定会失败,但它很容易修复。太好了!非常感谢。我为此使用正则表达式编写了一个很长的程序,因为我在限制块的数量方面遇到了问题……嗨,Sobrique,$header_line=;?你想让我把文件句柄放在while条件中吗?是的,如果你愿意的话。但这就是神奇的文件句柄,which可以读取STDIN或命令行上指定的文件。但是普通的应该也可以。哦,好的,我以前不知道这个。谢谢。我在命令提示符下传递了我的输入文本文件名,你的程序运行得很好。
my $prev_name;
while ( <FILE1> ) {
chomp $_;
my ( $name, $address ) = split /\s+/, $_, 2;
$hash{$prev_name = $name} ||= [] if $name;
push($hash{$name || $prev_name}, $address);
}