2013-06-01 12 views
6
my $line = "file1.gz file2.gz file3.gz"; 
my @abc = split('',$line); 
print "@abc\n"; 

oczekiwany wynik:podzielić ciąg w tablicy w Perl

file1.gz 
file2.gz 
file3.gz 

Chcę wyjście być file1.gz w $abc[0], file2.gz in $ abc [1] , and file3.gz in $ abc [2] ` . Jak podzielić?

+1

Cóż, nie język programowania może czytać w twoich myślach '' „” podział dzieli się na poszczególnych znaków Jeśli wszystkie nazwy plików rozpoczynające się od 'f.. ile ... ', wtedy' split/(? = file)/'działałoby, ale nie ma ogólnego rozwiązania – amon

+2

@aragaer Twój komentarz jest błędny. ['split'] (http://perldoc.perl.org/functions/split.html) przyjmuje argumenty jako wzór, łańcuch, limit. Twoje zamówienie jest nieprawidłowe. A "print" @abc \ n "' działałoby poprawnie, pod warunkiem, że '$" eq "\ n" '(' $ "' jest zwykle spacją). – amon

Odpowiedz

13

Dzielenie ciąg spacjami jest bardzo prosta:

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

Jest to szczególna forma split faktycznie (jak funkcja ta trwa zwykle wzory zamiast strun):

W innym szczególnym przypadku , split emuluje domyślne zachowanie narzędzia z wiersza poleceń awk, gdy PATTERN jest albo pominięte, albo literał ciąg złożony z pojedynczej spacji (takie jak ' ' lub "\x20"). W tym przypadku, wszelkie poprzedzające białe spacje w EXPR są usuwane przed usunięciem, a PATTERN jest traktowane jako , jeśli było to /\s+/; w szczególności oznacza to, że każda ciągła spacja (nie tylko pojedynczy znak spacji) jest używana jako separator.


Oto odpowiedź do pierwotnego pytania (z prostym ciągiem bez spacji):

Może chcesz podzielić na .gz rozszerzenia:

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

Tutaj użyłem (?<=...) skonstruować, czyli look-behind assertion, zasadniczo dokonując podziału w każdym punkcie linii poprzedzonym podciąganiem .gz.

Jeśli pracujesz z ustalonym zestawem rozszerzeń, można wydłużyć wzór ich wszystkich to:

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; 
+0

pytanie zostało zmienione na spacje – jamylak

+0

co to jest? <= W powyższym kodzie –

+0

@ user2384801 Dodano wyjaśnienie i link. – raina77ow

9

Mając $line jak jest teraz, po prostu można podzielić ciąg na podstawie co najmniej jednej spacji separator

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

następnie

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

lub

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

wolę korzystania () dla split, print i for.

+1

Powinieneś wiedzieć, że domyślny podział '' '' jest prawdopodobnie tym, czego szukasz zamiast '/ \ s + /'. Są dokładnie takie same, z wyjątkiem domyślnych pasków prowadzących do spacji przed dzieleniem. – TLP

+1

@TLP Wielkie dzięki - zawsze używałam '/ \ s + /' ignorując to domyślne '' '. Nadal uważam, że '/ \ s + /' jest łatwiejsze do zrozumienia, ponieważ robi to, co pokazuje ... Ale myślę, że '' '' jest łatwe do zapamiętania, robi dokładnie to, czego się chce (zazwyczaj nikt nie dba o to, aby jako pierwszy element był ciąg 0) i jest z pewnością zoptymalizowany, aby to zrobić bez kosztownego korzystania z regex. Odpowiedź zaktualizowana. –

+0

Nie ma za co. – TLP

0

Po prostu użyj/\ s +/przeciwko "" jako splitter. W tym przypadku usunięto wszystkie "dodatkowe" spacje. Zazwyczaj takie szczególne zachowanie jest wymagane. Tak więc, w twoim przypadku będzie to:

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

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

Znalazłem ten jeden bardzo prosty!

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"; 

wyjściowa:

file1.gz 
file2.gz 
file3.gz 

Tu przyjrzeć się tej lekcji, aby dowiedzieć się więcej na Perl regular expression i przewiń do więcej pasujących sekcję.

0

Witam Rahul Reddy,

Masz już wiele odpowiedzi na to pytanie, choć chciałbym dodać kolejny nieznaczna tutaj które mogłyby pomóc coś dodać.

Aby zobaczyć złożonych struktur danych w Perlu można użyć Data::Dumper a także drukować ciąg można użyć say, dodaje znak nowego wiersza (\n) po każdej struny zamiast robić to ręcznie.

Zwykle używam (\s), który pasuje (jeden) znak spacji, jeśli dodać (+) dopasowuje jedną lub więcej spacji (\s+). Możesz przeczytać więcej na ten temat tutaj perlre.

próbce Kod:.

#!/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); 

Nadzieja to pomaga, BR