我是perl的新手,正在尝试理解哈希。我尝试使用基本哈希及其工作。我现在正在尝试使用哈希哈希提取数据。例如,我有一个包含一些随机信息的文本文件(input.txt(。如何使用哈希结构的哈希提取所需的信息。
输入.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;
这将只给出一个哈希形式的条目。如何在输入文件中获得所有这些匹配项。
首先,您需要一些方法来避免文件开头的文本注释。 你可以跳过第一行,但是出现在其他地方的随机文本会把事情搞砸。 更好的办法是寻找相关数据,但无论它出现在何处,都乐于忽略任何其他文本。
请注意,文本注释包含相关数据:cell ("name")
但行尾没有{
。 你可以用它来区分评论和数据,但这可能有点太灵活了。 最好只在cell
声明之前坚持使用{
和空格。
一旦进入牢房,坚持不发表评论是合理的。 然后我们可以迭代读取行并在":"
上拆分,直到我们到达}
. 结合一些一般性建议;
- 将正则表达式定义与正则表达式使用分开。
- 在使用捕获变量之前测试匹配项;以及 使用允许在正则
- 表达式中使用空格的"扩展模式"正则表达式
这一切都给了我们;
#!/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;'
}
};