Perl 使用散列的散列来提取数据

Perl 使用散列的散列来提取数据,perl,hash,Perl,Hash,我是perl新手,正在尝试理解散列。我试过使用一个基本的散列及其工作原理。我现在尝试使用散列来提取数据。我有一个包含一些随机信息的文本文件(input.txt)。如何使用散列结构提取所需信息 输入文件 我想提取以下格式的单元格数据 输出 我试过这个: while(<$fh>) { if(/ cell \(/){$hash{cell} //=$_;} elsif(/ pin \(/){$hash{pin} //=$_;} elsif(/ valu

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

输入文件 我想提取以下格式的单元格数据

输出 我试过这个:

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

    elsif(/ value :/){$hash{value} //=$_;}
    }
    use Data::Dump;
    dd \%hash;
while()
{
如果(/cell\(/){$hash{cell}/=$\uz;}
elsif(/pin\(/){$hash{pin}/=$\}
elsif(/value:/){$hash{value}/=$\uz;}
}
使用数据::转储;
dd\%散列;

这将只提供一个散列形式的条目。如何才能在输入文件中获得所有这些匹配项。

首先,您需要某种方法避免文件开头的文本注释。您可以跳过第一行,但是其他地方出现的随机文本会把事情搞砸。最好是查找相关的data,但很高兴忽略任何其他文本,无论它出现在何处

请注意,文本注释包含相关的外观数据:
单元格(“名称”)
,但行尾没有
{
。您可以使用它来区分注释和数据,但这可能有点太灵活了。坚持使用
{
以及仅在
单元格
声明之前的空格

一旦进入一个单元格,坚持不发表评论是合理的。然后我们可以迭代地阅读行并在
”上拆分:“
,直到到达
}

  • 将regex定义与regex使用分开
  • 在使用捕获变量之前测试匹配项;以及
  • 使用允许在正则表达式中使用空格的“扩展模式”正则表达式
  • 这一切都给了我们

    #!/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;
    

    首先,您需要某种方法来避免文件开头的文本注释。您可以跳过第一行,但其他地方出现的随机文本会把事情搞砸。最好是查找相关数据,但不管其他文本出现在何处,都可以愉快地忽略它

    请注意,文本注释包含相关的外观数据:
    单元格(“名称”)
    ,但行尾没有
    {
    。您可以使用它来区分注释和数据,但这可能有点太灵活了。坚持使用
    {
    以及仅在
    单元格
    声明之前的空格

    一旦进入一个单元格,坚持不发表评论是合理的。然后我们可以迭代地阅读行并在
    ”上拆分:“
    ,直到到达
    }

  • 将regex定义与regex使用分开
  • 在使用捕获变量之前测试匹配项;以及
  • 使用允许在正则表达式中使用空格的“扩展模式”正则表达式
  • 这一切都给了我们

    #!/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;
    

    您好,欢迎使用Stack Overflow!您能告诉我们到目前为止您尝试了什么吗?我在que中编辑了它。我无法在所有匹配项中获得它,并且在表格形式中,该代码无法工作。我建议将此分为两个问题。首先让解析工作正常,只打印您捕获的内容。然后担心将其放入哈希中。请看一看不喜欢Hi,欢迎使用Stack Overflow!您能告诉我们您到目前为止尝试了什么吗?我在que中编辑了它。我无法在所有匹配项中获得它,并且在表格中该代码无法工作。我建议将其分为两个问题。首先让解析工作正常,只打印您正在捕获的内容。然后担心将其放入hash.看看它有什么帮助。我仍然在做一些更改。请告诉我为什么我们需要两个while循环?请。当我们有cell name时,它将被分配到$cell\u name。然后它将如何再次检查while()第二个。我们需要两个while循环,因为我们在寻找两个不同的东西。当我们在单元格外时,我们在寻找
    单元格(名称)
    ,但一旦我们找到它并进入单元格内,我们就在寻找
    某物:某物
    }
    。该程序有两种模式,但两种模式都需要读取行来处理。因此,我们需要两个循环。外循环扫描查找单元格,内循环扫描查找组成单元格的数据。HTH。如果我错了,请联系我:让我们先获取单元格名称。然后,单元格名称后的行将出现,它将跳转到下一行,原因是!=/$cell\u name\u re/第一个while的条件。这很有帮助。我仍然在做一些更改。请告诉我为什么我们需要两个while循环?请。当我们有了cell name时,它将被分配给$cell\u name。然后它将如何再次检查while()第二个。我们需要两个while循环,因为我们在寻找两个不同的东西。当我们在单元格外时,我们在寻找
    单元格(名称)
    ,但一旦我们找到它并进入单元格内,我们就在寻找
    某物:某物
    }
    。该程序有两种模式,但两种模式都需要读取行来处理。因此,我们需要两个循环。外循环扫描查找单元格,内循环扫描查找组成单元格的数据。HTH。如果我错了,请联系我:让我们先获取单元格名称。然后,单元格名称后的行将出现,它将跳转到下一行,原因是!=/$cell\u name\u re/从第一个while开始的条件。
    #!/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;
    
        {
          'name' => {
                      'function' => ' A+B;',
                      'value' => ' 0.435;',
                      'pin ' => ' A, B;'
                    }
        };