我有一个.sql文件,我正在阅读我的输入。假设该文件包含以下输入....
Message Fruits Fruit="Apple",Color="Red",Taste="Sweet";
Message Flowers Flower="Rose",Color="Red";
现在我编写了一个perl脚本来从这个文件生成哈希..
use strict;
use Data::Dumper;
if(open(MYFILE,"file.sql")){
my @stack;
my %hash;
push @stack,\%hash;
my @file = <MYFILE>;
foreach my $row(@file){
if($row =~ /Message /){
my %my_hash;
my @words = split(" ",$row);
my @sep_words = split(",",$words[2]);
foreach my $x(@sep_words){
my($key,$value) = split("=",$x);
$my_hash{$key} = $value;
}
push @stack,$stack[$#stack]->{$words[1]} = {%my_hash};
pop @stack;
}
}
print Dumper(\%hash);
}
我得到以下输出..
$VAR1 = {
'Flowers' => {
'Flower' => '"Rose"',
'Color' => '"Red";'
},
'Fruits' => {
'Taste' => '"Sweet";',
'Fruit' => '"Apple"',
'Color' => '"Red"'
}
};
现在这里的哈希不保留读取输入的顺序。我希望我的哈希与输入文件的顺序相同。 我找到了像Tie :: IxHash这样的库,但是我想避免使用任何库。任何人都可以帮我解决???
答案 0 :(得分:4)
对于低密钥方法,您可以始终将密钥保存在数组中,该数组确实有订单。
foreach my $x(@sep_words){
my($key,$value) = split("=",$x);
$my_hash{$key} = $value;
push(@list_keys,$key);
}
然后提取,遍历键
foreach my $this_key (@list_keys) {
# do something with $my_hash{$this_key}
}
但确实存在这个问题,你依赖于密钥数组和散列保持同步。如果您不小心,也可能会多次意外添加相同的密钥。
答案 1 :(得分:3)
Joel说得对 - 你无法可靠地信任Perl中哈希的顺序。如果您需要某个订单,则必须将您的信息存储在一个数组中。
答案 2 :(得分:2)
哈希是一组具有唯一键的键值对。套装本身从不订购。
数组是任意数量标量的序列。数组本身是有序的,但必须在外部强制执行唯一性。
以下是我对你的问题的看法:
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
local $/ = ";\n";
my @messages;
while (<DATA>) {
chomp;
my ($msg, $to, $what) = split ' ', $_, 3; # limit number of fragments.
my %options;
while($what =~ /(\w+) = "((?:[^"]++|\\.)*)" (?:,|$)/xg) {
$options{$1} = $2;
}
push @messages, [$to => \%options];
}
print Dumper \@messages;
__DATA__
Message Fruits Fruit="Apple",Color="Red",Taste="Sweet";
Message Flowers Flower="Rose",Color="Red";
我将消息放入数组中,因为它必须进行排序。另外,我不会做一些我不需要的奇怪的体操。
我不会拆分所有换行符,因为您可以使用包含换行符的引用值。出于同样的原因,我不会盲目地分开,
或=
并使用合理的正则表达式。可能值得添加错误检测,例如最后的die if not defined pos $what or pos($what) != length($what);
(在regex上需要/c
标志),以查看我们是否实际处理了所有内容或者是否过早地抛出循环。
这会产生:
$VAR1 = [
[ 'Fruits',
{
'Taste' => 'Sweet',
'Fruit' => 'Apple',
'Color' => 'Red'
}
],
[ 'Flowers',
{
'Flower' => 'Rose',
'Color' => 'Red'
}
]
];
(与其他缩进,但这无关紧要)。
存在一个问题:文件必须以换行符终止,否则最后一个分号不会被捕获。