Разбить строку на массив в Perl



my $line = "file1.gz file2.gz file3.gz";
my @abc = split('', $line);
print "@abcn";


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



file1.gz
file2.gz
file3.gz


Я хочу, чтобы выход был file1.gz в $abc[0], file2.gz в $abc[1] и file3.gz в $abc[2]. Как мне разделить $line?

832   5  

5 ответов:

Разбить строку на пробелы очень просто:

print $_, "\n" for split ' ', 'file1.gz file1.gz file3.gz';

Это специальная форма split На самом деле (поскольку эта функция обычно принимает шаблоны вместо строк):

Как еще один частный случай, split эмулирует поведение по умолчанию инструмент командной строки awk, Когда PATTERN либо опущен, либо является литералом строка, состоящая из одного пробела (например, ' ' или "\x20"). В этом случае любой начальный пробел в EXPR равен удаляется до того, как произойдет расщепление, и PATTERN вместо этого рассматривается как если бы это было /\s+/; в частности, это означает, что любое смежное в качестве разделителя используется пробел (а не один символ пробела).


Вот ответ на исходный вопрос (с простой строкой без пробелов):

Возможно, вы хотите разделить на .gz расширение:

my $line = "file1.gzfile1.gzfile3.gz";
my @abc = split /(?<=\.gz)/, $line;
print $_, "\n" for @abc;

Здесь я использовал (?<=...) конструкцию, которая является скрытым утверждением , в основном делая расщепление в каждой точке линии перед подстрокой .gz.

Если вы работаете с фиксированным набором расширений, вы можете расширить шаблон, чтобы включить их все:

my $line = "file1.gzfile2.txtfile2.gzfile3.xls";
my @exts = ('txt', 'xls', 'gz');
my $patt = join '|', map { '(?<=\.' . $_ . ')' } @exts;
my @abc = split /$patt/, $line;
print $_, "\n" for @abc;

Имея $line как сейчас, вы можете просто разделить строку на основе по крайней мере одного разделителя пробелов

my @answer = split(' ', $line); # creates an @answer array

Затем

print("@answer\n");               # print array on one line

Или

print("$_\n") for (@answer);      # print each element on one line

Я предпочитаю использовать () для split, print и for.

Просто используйте /\s+ / against " в качестве разделителя. В этом случае все "лишние" заготовки были удалены. Обычно требуется именно такое поведение. Итак, в вашем случае это будет:

my $line = "file1.gz file1.gz file3.gz";
my @abc = split(/\s+/, $line);

for my $i in (@abc) {
    print "$i\n";
}

Я нашел, что это очень просто!

my $line = "file1.gz file2.gz file3.gz";

my @abc =  ($line =~ /(\w+[.]\w+)/g);

print $abc[0],"\n";
print $abc[1],"\n";
print $abc[2],"\n";

Вывод:

file1.gz 
file2.gz 
file3.gz

Здесь взгляните на этот учебник, чтобы найти больше о регулярном выражении Perl и прокрутите вниз до раздела More matching.

У вас уже есть несколько ответов на ваш вопрос, но я хотел бы добавить еще один незначительный, который может помочь добавить что-то.

Для просмотра структур данных в Perl можно использовать Data::Dumper. Для печати строки можно использовать say, который добавляет символ новой строки "\n" после каждого вызова вместо того, чтобы добавлять его явно.

Я обычно использую \s, который соответствует символу пробела. Если вы добавляете +, он соответствует одному или нескольким символам пробела. Вы можете читать подробнее об этом здесь perlre.

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

use feature 'say';

my $line = "file1.gz file2.gz file3.gz";
my @abc  = split /\s+/, $line;

print Dumper \@abc;
say for @abc;

Comments

    Ничего не найдено.