如何根据 Perl 中的特定正则表达式将文件中的值分组到散列中?

How do I group values from a file into a hash according to specific Regular Expressions in Perl?

我有一个 .txt 文件,其中一列包含数据,如下所示:

state_1
state_2
state_3
input_11
input_12
input_13
input_21
input_22
input_31

我想根据它们的名称和编号将这些标签分组到一个 hash 中:

state_1:              # For state_1, we have all "input1x" data tags
  -input_11
  -input_12
  -input_13
state_2:              # For state_2, we have all "input2x" data tags
  -input_21
  -input_22
state_3:              # For state_3, we have all "input3x" data tags
  -input_31

我尝试使用 push 函数 like in this case 尝试将值作为数组强制放入散列中 push @{ $state{$inputs} }, $_;,但我无法找到一种循环并获取根据正则表达式所需的哈希值。

我也研究了如何 group my data according to regex,但我仍然找不到对从 .txt 文件中获取的数据进行分组的方法。

我的问题是,我在寻找什么才能对这些标签进行相应的分组?

简而言之,从一行数据中提取该索引(12...)并使用它来形成正确的键并将该行添加到该键的 arraref,也依赖自生

push @{$data{"state_"}}, $line  if $line =~ /input_([0-9])/; 

在数据 input_NN 的行上,正则表达式提取 input_ 之后的第一个数字,并将该行添加到 arrayref 的适当键处。要添加的键名是使用捕获的数字和固定前缀构建的。密钥的第一次循环,在它被看到之前,因此它还不在哈希中,它是由名为 autovivification 的 mechanism/feature 创建的。

然后是一些细节——如果真实数据中有什么,而不是令牌名称 inputstate,事先不知道,那么可以提取它从第一行数据开始,然后像上面那样使用。读取行时需要删除换行符。一共

use warnings;
use strict;
use feature 'say';

use Data::Dump qw(dd);   # to see complex data; or, use core Data::Dumper

my %data;

while (<>) {  # reads line by line the files given on command line
    chomp;

    push @{$data{"state_"}}, $_  if /input_([0-9])/;
}

dd \%data;

这假设 keys/data 具有固定前缀并且这些前缀是已知的(stateinput)。


一个one-liner例子

perl -MData::Dump -wnlE'push @{$h{"state_"}}, $_ if /input_([0-9])/; }{ dd \%h' file

其中 file 包含问题中给出的内容。 }{ 启动 END phase -- 之后的代码在读取所有行并完成处理后执行,RUN 阶段完成并且程序即将退出.


这是一个功能,当一个未定义的值(对象所在的位置)在“左值上下文”(它需要“可修改”)。

上面的一个具体示例:我们通过添加作为其值的数组引用 push @{ $data{state_1} }, $value 来“使用”(取消引用)键 state_1(等)——但没有这样的键有第一次!好吧,它是为我们即时制作的。

例如,请参阅有关何时启动或不启动的文章 from The Effective Perler, and then there is far more of it around. Here are some generic examples and discussion, and here is a

条目来自 perlglossary

In Perl, storage locations (lvalues) spontaneously generate themselves as needed, including the creation of any hard reference values to point to the next level of storage. The assignment $a[5][5][5][5][5] = "quintet" potentially creates five scalar storage locations, plus four references (in the first four scalar locations) pointing to four new anonymous arrays (to hold the last four scalar locations). But the point of autovivification is that you don’t have to worry about it.