Perlでのsplit関数の正しい使用について誰かが私を助けてくれますか?
これが@input_linesと呼ばれる私の入力リストです:
google.com/test
yahoo.com/test
##############
somethingelse.com/test
##############
12345
my(@first_array,@second_array,@rand_no) = split(/^\#+/, @input_lines);
私はあなたが本当に何を意味するのか推測します:
最初は、おそらくinput.txt
次のコンテンツを含むテキスト入力ファイルがあります。
google.com/test
yahoo.com/test
##############
somethingelse.com/test
##############
12345
ここで、14個の「#」で区切られたレコードをファイルから分離しようとしています。したがって、##############
としてファイルを読み取るだけで、次のように実行できますinput record separator
。
...
my $fn = 'input.txt'; # set the file name
open my $fh, '<', $fn or die $!; # open the file
$/="\n##############\n"; # set the input record separator
my @parts = <$fh>; # read the file record-wise
chomp @parts; # remove the record separator from data
close $fh # close the file
...
現在の要素に@parts
は、次の内容が含まれています。
$parts[0]
google.com/test
yahoo.com/test
$parts[1]
somethingelse.com/test
$parts[2]
12345
異なるサイズの-separatorを探す必要がある場合は、1回の読み取り操作でファイルを丸呑みし、後でセパレーターで分割することで、#
これと非常によく似た方法でこれを実現できます。
...
my $fn = 'input.txt';
open my $fh, '<', $fn or die $!;
undef $/; # remove the input record separator
my @parts = split /\n#+\n/, <$fh>; # read file as a block and split
close $fh;
...
同じ結果になります。
よろしく
rbo
脚本:
my @input_lines = <main::DATA>;
my $input_string = join /\n/, @input_lines;
my @split_lines = split(/\s*[#\n\r]+\s*/, $input_string);
print "$_\n" for @split_lines;
__DATA__
google.com/test
yahoo.com/test
##############
somethingelse.com/test
##############
12345
出力:
google.com/test
yahoo.com/test
somethingelse.com/test
12345
こちらのコードを参照してテストしてください。
脚本:
use Data::Dumper;
my @input_lines = <main::DATA>;
my $input_string = join /\n/, @input_lines;
my @blocks = split(/\s*#+\s*/, $input_string);
my @matches = ();
push @matches, [ split(/\s*[\n\r]+\s*/, $_) ] for @blocks;
print Dumper(@matches);
__DATA__
google.com/test
yahoo.com/test
##############
somethingelse.com/test
##############
12345
出力:
$VAR1 = [
'google.com/test',
'yahoo.com/test '
];
$VAR2 = [
'somethingelse.com/test '
];
$VAR3 = [
'12345'
];
こちらのコードを参照してテストしてください。
@input_lines文字列の形式が同じである場合は、すべての文字列を同様に結合してから、パーツごとに分割できます。/^#+/
あなたの場合、使用分割が間違っている ことに注意する必要があります。
my $line = join ',', @input_lines;
my ($first_part, $second_part, $third_part) = split /\#+/, $line;
my @first_array = split ',', $first_part;
my @second_array = split ',', $second_part;
my @third_array = split ',', $third_part;
split
配列ではなく文字列で動作します。また、同じ割り当てで複数の配列に割り当てることはできません。右側のリストがフラット化されるため、最初の配列がすべてを取ります。
更新:このコードは機能しますが、次のようになります。
my (@first, @second, @rand);
for my $array (\@first, \@second, \@rand) {
my $line;
do {
push @$array, $line = shift @input_lines
} until $line =~ /^#+/ or ! @input_lines;
pop @$array if @input_lines; # Remove the separators
}
あなたはこのようなことをすることができます。$output
配列の1つを表す各要素の配列refがあります。
use strict; use warnings;
use Data::Dumper;
my @input_lines = (
'google.com/test',
'yahoo.com/test',
'##############',
'somethingelse.com/test',
'##############',
'12345',
);
my $output = []; # array ref
my $rand_no;
my $i = 0;
foreach my $line (@input_lines) {
if ($line =~ m/^#+$/) {
# if it's the # we move to the next index
$i++;
next;
}
elsif ($line =~ m/^\d+$/) {
# this is the random numer
$rand_no = $line;
} else {
# everything else goes into the current index
push @{ $output->[$i] }, $line;
}
}
print Dumper $output, $rand_no;
出力:
$VAR1 = [
[
'google.com/test',
'yahoo.com/test'
],
[
'somethingelse.com/test'
]
];
$VAR2 = '12345';
入力行がにあると仮定すると$string
(そうでない場合はを使用join "\n", @input_lines
)、次split
のように使用できます。
($first, $second, $rand_no) = split /\n#+\n/m, $string;
print "`", $_, "`\n" for (@fields)'