Прочитать все строки между совпадением с образцом, используя Perl - PullRequest
0 голосов
/ 30 апреля 2019

Я хочу прочитать CSV-файл. CSV-файлы, как показано ниже,

cat,dog,0
apple,banana,0
#start_loop
jug,ball,0
tub, jar,3
#stop_loop
phone,bottle,10
#per head
#start_loop
cup,book,7
laptop,charger,9
#stop_loop

Для вышеупомянутого csv я хочу прочитать между #start и #stop. Кроме того, я хочу различить два #start_loop для ex, строки из первого #start_loop идут в один массив, а другой #start_loop идет в другой массив.

Ожидаемый результат будет:

@array1 = {jug ball 0, tub jar 3}

и

@array2 = { cup book 7, laptop charger 9}

Как мне решить эту проблему?

Ответы [ 2 ]

4 голосов
/ 30 апреля 2019

Вы можете использовать оператор триггера.Это значение будет равно 1 для строки #start и будет содержать E для строки #stop.

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

my @arr;

while (<>) {
    chomp;
    my $inside = /^#start_loop/ .. /^#stop_loop/;
    if ($inside) {
        push @arr, [] if 1 == $inside;
        undef $inside if 1 == $inside
                      || $inside =~ /E/;
        push @{ $arr[-1] }, $_ if $inside;
    }
}

use Data::Dumper; print Dumper \@arr;
3 голосов
/ 30 апреля 2019

Упрощенная версия решения Чоробы:

my @arr;
while (<>) {
    chomp;
    my $inside = /^#start_loop/ .. /^#stop_loop/;
    if    ( $inside == 1   ) { push @arr, [];          }  # Start line
    elsif ( $inside !~ /E/ ) { push @{ $arr[-1] }, $_; }  # Middle line
}

Без триггера:

my @arr;
my $inside;
while (<>) {
    chomp;
    if    ( /^#start_loop/ ) { $inside = 1; push @arr, []; }  # Start line
    elsif ( /^#stop_loop/  ) { $inside = 0;                }  # Stop line
    elsif ( $inside        ) { push @{ $arr[-1] }, $_;     }  # Middle line
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...