0

入力ファイルがあります

入力ファイル.txt

        name: George
         age: 5
      nature: curious
       likes: banana

これを私はフォーム レイアウトと呼んでいます。これをテーブル レイアウトの CSV に変換しようとしています。例えば:

name,age,nature,likes
George,5,curious,banana

そのため、ファイルを読み取り、「: と \n」で分割し、値をハッシュに配置します。次に、そのハッシュを配列にプッシュして、後で取り出せるようにします。これが私がこれまでに行ったことです。

#!/usr/bin/perl
use strict;

 open (MYFILE, 'inputfile.txt');
 my @records;
 while (<MYFILE>) {
        chomp;
        my %values = split(/[:\n]/,$_);
        push @records,%values;
 }
 close (MYFILE);

これによって、私@records={[name=George],[age=5],[nature=curious],[likes=banana]}は起こっただろうと思います。

では、配列から各ハッシュを取得するにはどうすればよい@recordsでしょうか。次のようなものを試すと:

 foreach my $record(@records){
     my %record = $record;
     for my $key(keys %record){
        print "key : $key\n";
     }
 }

予想とは異なり(キーのみ)、すべてのトークンを次々に出力します。

4

1 に答える 1

5

少し違う方法でやります…

my (@values, @properties);
while (<DATA>) {
  if (/(\S*)\s*:\s*(\S*)/) {
    push @values, $1;
    push @properties, $2;
  }
}
print join ',', @values;
print "\n";
print join ',', @properties;
print "\n";
__DATA__
        name: George
         age: 5
      nature: curious
       likes: banana

... 2 つの理由から。

まず、Perl のハッシュは順序付けされておらず、これらのプロパティを並べ替えて元の状態に戻す簡単な方法はありません。このような場合は、配列を使用することをお勧めします。

第 2 に、代わりに正規表現一致をsplit使用すると、不正なデータをより簡単に処理できます (このコードでは、パターンは非常に単純ですが、検証ロジックを取得するのは非常に簡単です)。さらに、データのすべてのチャンクがすぐにキャプチャされます。chomp追加で変換する必要はありません。


元のコードといえば、この行...

push @records, %values;

... に書き換える必要がありました ...

push @records, \%values;

...使用可能なものを意味します。配列は Perl でフラット化されることを思い出してください。ハッシュを配列にプッシュしようとすると、リストに変換されるだけです (そして、このリストがその配列に追加されます)。

それでも、そのようなハッシュの配列を出力する必要がある場合は、その要素のキーを調べてから、その要素の値を調べる必要があります。私のコードのように、これらを別々に保存するだけであれば、必要ありません。

于 2012-09-26T16:23:50.657 に答える