4

次のBibTeXファイル(bibliography.bib)を解析しようとしています:

@book{Lee2000a,
abstract = {Abstract goes here},
author = {Lee, Wenke and Stolfo, Salvatore J},
title = {{Data mining approaches for intrusion detection}},
year = {2000}
}
@article{Forrest1996,
abstract = {Abstract goes here},
author = {Forrest, Stephanie and Hofmeyr, Steven A. and Anil, Somayaji},
title = {{Computer immunology}},
year = {1996}
}

期待どおりに機能するパッケージを使用してBibTeX::Parserいますが、問題はハッシュ構造のハッシュの作成にあります。これは私のコードです:

#!/usr/bin/perl
# http://search.cpan.org/~gerhard/BibTeX-Parser-0.62/lib/BibTeX/Parser.pm
use BibTeX::Parser;
use IO::File;
use Data::Dumper;
use strict;
use warnings;

my $filename="bibliography.bib";
my (%bibliography, %article);
my $i;
my ($entry, @entries, $type, $key);
my (my $hkey, my $hvalue);

# open BibTeX
my $fh = IO::File->new("$filename") or die "could not open $filename: $!\n";

# create parser object ...
my $parser = BibTeX::Parser->new($fh);

# ... and iterate over entries
while ($entry = $parser->next ) {
  if ($entry->parse_ok) {

    # return BibTeX elements like abstract, author, title ...
    @entries = $entry->fieldlist();

    # create %article as a hash array e.g. year -> 1996; isbn -> 1581138709 etc.
    foreach (@entries) {
      $article{"$_"} = $entry->field("$_");
    }

    # return article's key (Lee2000a, Forrest1996)
    $key = $entry->key;

    # append %article into %bibliography with approporiate key
    $bibliography{"$key"} = \%article;

    #Debug
    #print $entry->key, "\n";
    #print Dumper (\%article);

    # removes all elements of %article (prepare for next iteration)
    %article = ();

    #Debug
    #print "================================\n";
  }

  else {
    warn "Error parsing file: " . $entry->error;
 }
}

    #Debug
    #print Dumper (\%bibliography);

の現在の出力Dumper (\%bibliography):

$VAR1 = {
          'Lee2000a' => {},
          'Forrest1996' => $VAR1->{'Lee2000a'}
        };

の望ましい出力Dumper (\%bibliography):

$VAR1 = {
          'Lee2000a' => {
                'abstract' => 'Abstract goes here',
                'author' => 'Lee, Wenke and Stolfo, Salvatore J'
                'title' => 'Data mining approaches for intrusion detection'
                'year' => '2000'
              },
          'Forrest1996' => {
                'abstract' => 'Abstract goes here',
                'author' => 'Forrest, Stephanie and Hofmeyr, Steven A. and Anil, Somayaji'
                'title' => 'Computer immunology'
                'year' => '1996'
                }
        };

私がしていることは間違っていますか?どうもありがとう。

4

2 に答える 2

2

この行なしでコードを試してください:

# removes all elements of %article (prepare for next iteration)
%article = ();

そのハッシュへの参照として $bibilography{$key} を設定し、それを空にしています。

また、 %article の宣言をループ内に移動します (おそらく の直後に移動if ($entry->parse_ok) {して、そのスコープが使用している場所に対してローカルになり、再初期化が不要になるようにします。

それが役立つことを願っています...

並べ替えの質問を含めるように更新しています...これはハッシュを並べ替えるために機能するはずです:

foreach my $bib_key ( sort keys %bibliography ) {
  print "$bib_key\n";

  foreach my $article_key (sort keys %{ $bibliography{$bib_key} }) {
    print "\t $article_key: $bibliography{$bib_key}{$article_key}\n";
  }
}
于 2012-12-07T14:05:07.193 に答える
1

ダンパー出力

$ VAR1 = {'Lee2000a' => {}、'Forrest1996' => $ VAR1-> {'Lee2000a'}};

は、ハッシュが構造を共有していること、つまり、が同じ記事のハッシュ$bibliography->{Lee2000a}への$bibliography->{Forrest1996}参照であることを示しています。コードには外部スコープがあり、ループを繰り返すたびに、この共有ハッシュがクリーンアップされて再入力されます。my %article

代わりに、各反復で新しい内部記事ハッシュを作成する必要があります。アウター%articleを取り外して、下に(+)のマークが付いているループに移動します。%article = ()収集したデータが破壊される行を削除します。

while ($entry = $parser->next) {
  if ($entry->parse_ok) {
    # return BibTeX elements like abstract, author, title ...
    @entries = $entry->fieldlist();

    # create %article as a hash array e.g. year -> 1996; isbn -> 1581138709 etc.
    my %article;  # (+)
    foreach (@entries) {
      $article{$_} = $entry->field($_);
    }

    # return article's key (Lee2000a, Forrest1996)
    $key = $entry->key;

    # insert %article into %bibliography with appropriate key
    $bibliography{$key} = \%article;
  }
  else {
    warn "Error parsing file: " . $entry->error;
  }
}
于 2012-12-07T16:37:15.203 に答える