使用散列哈希来提取数据

时间:2016-04-18 04:31:57

标签: perl hash

我是perl的新手并且正在尝试理解哈希。我尝试过使用基本哈希及其工作方式。我现在正试图使用​​散列哈希来提取数据。例如,我有一个包含一些随机信息的文本文件(input.txt)。如何使用哈希结构哈希提取所需信息。

input.txt中

hi how r you this is sample .txt. you can use it for learning hash and hash of hashes. Let say I have cell ("name") and it has value as below
cell ("name"){
  pin : A, B;
  function: A+B;
  value: 0.435;
}

我想以下列格式提取单元格数据。

输出

  Cell    Pin   Value
  name     A    0.435

我试过了:

  while(<$fh>)
     {
    if(/ cell \(/){$hash{cell} //=$_;}
    elsif(/ pin \(/){$hash{pin} //=$_;}

    elsif(/ value :/){$hash{value} //=$_;}
    }
    use Data::Dump;
    dd \%hash;

这将只以哈希形式提供一个条目。如何在输入文件中获得所有这些匹配。

1 个答案:

答案 0 :(得分:0)

首先,您需要一些方法来避免文件开头的文本注释。你可以跳过第一行,但随后出现在其他地方的随机文本会搞砸。更好的方法是查找相关数据,但无论出现在何处,都会高兴地忽略任何其他文本。

请注意,文字评论包含相关外观的数据:cell ("name")但该行末尾没有{。您可以使用它来区分评论和数据,但这可能有点过于灵活。可能最好只在{声明之前坚持cell以及空格。

一旦进入牢房,坚持不做任何评论是合理的。然后我们可以迭代地读取行并在":"上拆分,直到我们到达}。结合一些一般性建议;

  1. 从正则表达式使用中分离出正则表达式定义。
  2. 在使用捕获变量之前测试您的匹配项;和
  3. 使用&#39;扩展模式&#39;允许正则表达式中的空格的正则表达式
  4. 这一切都给了我们;

    #!/usr/bin/env perl
    use v5.12;
    use Data::Dumper qw(Dumper);
    
    my $cell_name_re =      qr/ ^ \s* cell \s* \( \s* "(\w+)" \) \s* { /x;
    my $cell_data_re =      qr/ ^ \s* ([^:]+) : (\N+)  \n /x;
    my $closing_curly_re =  qr/ ^ \s* }  /x;
    
    my %data ;
    while (<>) {
        next unless /$cell_name_re/ ;
        my $cell_name = $1 ;
    
        my %cell_hash ;
        while (<>) {
            if ( /$cell_data_re/ )  {
                $cell_hash{ $1 } = $2 ;
            }
            elsif ( /$closing_curly_re/ )  {
                $data{ $cell_name } = \%cell_hash ;
                last ;        # exit the inner loop
            }
            else {
                warn "Don't understand line $. - ignoring" ;
            }
        }
    }
    print Dumper( \%data );
    exit 0;
    

    这里有两个关键的事情 - 首先,%cell_hash在第一个循环中被声明,这确保我们每次都获得一个新的%cell_hash;当我们将%cell_hash插入全局%data时,我们会使用\对其进行引用。运行它上面的输入数据产生;

        {
          'name' => {
                      'function' => ' A+B;',
                      'value' => ' 0.435;',
                      'pin ' => ' A, B;'
                    }
        };