3

私はプロパティファイルを持っています

##
## Start of property1
##
##
Property1=\
a:b,\
a1:b1,\
a2,b2
##
## Start of propert2
##
Property2=\
c:d,\
c1:d1,\
c2,d2

特定のプロパティの値は、複数の行に分割される場合があることに注意してください。

このプロパティ ファイルを Perl を使用して読み取りたいと考えています。Java はバックスラッシュを使用して複数行の値をサポートしているため、これは Java では問題なく機能しますが、Perl では悪夢です。

上記のプロパティ ファイルには 2 つのプロパティがありProperty1、それぞれが区切り文字とProperty2区切り記号に基づいて分割できる文字列に関連付けられています。,:

特定のプロパティ (たとえばProperty1) と特定の列 (たとえば) について、2 番目の列 (ここ)a1を返す必要があります。b1

コードは、コメント、スペースなどを無視できる必要があります。

前もって感謝します

4

2 に答える 2

5

バックスラッシュ継続行の処理を含むほとんどのテキスト処理は、Perl では非常に単純です。必要なのは、このような読み取りループだけです。

while (<>) {
  $_ .= <> while s/\\\n// and not eof;
}

以下のプログラムは、私があなたが望むと思うことを行います。print継続行にわたって集約された完全なレコードを表示するために、読み取りループに呼び出しを入れました。b1また、例として挙げたフィールドを抽出する方法を示し、Data::Dump作成されたデータ構造を確認できるように出力を示しました。

use strict;
use warnings;

my %data;

while (<DATA>) {
  next if /^#/;
  $_ .= <DATA> while s/\\\n// and not eof;
  print;
  chomp;
  my ($key, $values) = split /=/;
  my @values = map [ split /:/ ], split /,/, $values;
  $data{$key} = \@values;
}

print $data{Property1}[1][1], "\n\n";

use Data::Dump;
dd \%data;


__DATA__
##
## Start of property1
##
##
Property1=\
a:b,\
a1:b1,\
a2,b2
##
## Start of propert2
##
Property2=\
c:d,\
c1:d1,\
c2,d2

出力

Property1=a:b,a1:b1,a2,b2
Property2=c:d,c1:d1,c2,d2
b1

{
  Property1 => [["a", "b"], ["a1", "b1"], ["a2"], ["b2"]],
  Property2 => [["c", "d"], ["c1", "d1"], ["c2"], ["d2"]],
}

アップデート

あなたの質問をもう一度読みましたが、データの別の表現を好むかもしれません。このバリアントは、プロパティ値を配列の配列ではなくハッシュとして保持します。それ以外の場合、その動作は同じです

use strict;
use warnings;

my %data;

while (<DATA>) {
  next if /^#/;
  $_ .= <DATA> while s/\\\n// and not eof;
  print;
  chomp;
  my ($key, $values) = split /=/;
  my %values = map { my @kv = split /:/; @kv[0,1] } split /,/, $values;
  $data{$key} = \%values;
}

print $data{Property1}{a1}, "\n\n";

use Data::Dump;
dd \%data;

出力

Property1=a:b,a1:b1,a2,b2
Property2=c:d,c1:d1,c2,d2
b1

{
  Property1 => { a => "b", a1 => "b1", a2 => undef, b2 => undef },
  Property2 => { c => "d", c1 => "d1", c2 => undef, d2 => undef },
}
于 2012-10-09T13:10:58.767 に答える
0

ファイルが大きすぎないと仮定すると、次の簡単な方法があります。

use strict;
use warnings;

open FILE, "my_file.txt" or die "Can't open file!";

{
    local $/;
    my $file = <FILE>;
    #If \ is found at the end of the line, delete the following line break.
    $file =~ s/\\\n//gs;
}

行が で終わるたび\に、次の改行が削除されます。これにより、各複数行のプロパティが 1 行に配置されます。

欠点は、これがファイル全体をメモリに読み込むことです。入力ファイルが非常に大きい場合は、ファイルを 1 行ずつ処理するアルゴリズムに適応させることができます。

于 2012-10-09T12:43:41.190 に答える