在perl中,访问存储在单个数组元素中的多行之一

时间:2014-01-02 02:06:19

标签: arrays perl split

我有这个示例文本,我想从单个数组元素中访问多行中的一行。

Student 1:
Math 83
Chemistry 60
Physics 75

Student 2:
Math 69
Chemistry 76
Physics 73
Art A-

我将多行存储到单个数组元素的脚本如下:

use strict;
use warnings;

open my $fh, '<', 'Text1' or die "Could not open file to read:$!";
my $file = do { local $/; <$fh> };
my @a = split /\n\n/, $file;
close $fh;

print "First array element is $a[0]\n";
print "Second array element is $a[1]\n";

输出

First array element is Student 1:
Math 83
Chemistry 60
Physics 75
Second array element is Student 2:
Math 69
Chemistry 76
Physics 73
Art A-

我是否有更好的方法来访问和获取阵列的第一个或第二个元素中的多条线之一以供进一步使用?即,我需要每个学生Math score。 这是我到目前为止所提出的,加入数组的第一个元素并再次拆分它们。提前谢谢。

use strict;
use warnings;

open my $fh, '<', 'Text1' or die "Could not open file to read:$!";
my $file = do { local $/; <$fh> };
my @a = split /\n\n/, $file;
close $fh;

print "First array element is $a[0]\n";
print "Second array element is $a[1]\n";

my $str=join('',$a[0]);
my @score1 = split('\n',$str);
$str=join('',$a[1]);
my @score2 = split('\n',$str);

print "Student 1 : $score1[1]\n";
print "Student 2 : $score2[1]\n";

2 个答案:

答案 0 :(得分:3)

通过将$/设置为"",您可以一次阅读一个“段落”,而不是“啜饮”整个文件。我会使用哈希而不是@score1@score2。然后,您可以使用数学作为关键来解决所寻求的数学分数。它看起来像这样 -

#!/usr/bin/perl
use strict;
use warnings;

my @grades;

{
    local $/ = "";
    while (<DATA>) {
        push @grades, { split };
    }   
}

for my $href (@grades) {
    print "student: $href->{Student} Math: $href->{Math}\n";    
}

输出 -

student: 1: Math: 83
student: 2: Math: 69

答案 1 :(得分:3)

您的阅读和分割可以简化为使用readline的段落模式:

my @student = do { local $/ = ""; <$fh> };

我倾向于将每个学生分成一个哈希:

my @student = map {
    my ($student, $scores) = /\A(.*):\n(.*)/s;
    {
        'Name' => $student,
        split ' ', $scores
    }
} do { local $/ = ""; <$fh> };

for my $student_number (0..1) {
    print "Name: $student[$student_number]{Name}  Math Score: $student[$student_number]{Math}\n";
}

如果学生之间没有空白行:

my @student;
my $current_student;
while ( my $line = <$fh> ) {
    if ( my ($name) = $line =~ /^(.*):/ ) {
        $current_student = { 'Name' => $name };
        $line =~ s/^.*://;
        push @student, $current_student;
    }
    my @scores = split ' ', $line;
    while ( my ($subject, $score) = splice(@scores, 0, 2) ) {
        $current_student->{$subject} = $score;
    }
}

(主题必须与其得分在同一行。)