使用 perl 进行哈希键排序?
Hash key sorting using perl?
我需要使用 perl 对散列键进行排序,我还需要允许重复的键。所以我计划检查 perlexists
中的方法
如果它存在然后我增加最后一个数字然后我将存储到哈希中。
我尝试了以下代码:
use strict;
use warnings;
use iPerl::Basic qw(_save_file _open_file);
my $xml = $ARGV[0];
my ($xmlcnt,$backcnt,$refcnt,$name,$year) = "";
my %sort = ();
if(($#ARGV != 0) or(not -f "$xml") or($xml!~ m{\.xml$}i)){
print_exit("\t\tSYSTAX ERROR: <EXE> <xml File>\n\n")
};
$xmlcnt=_open_file($xml);
$xmlcnt =~ s{<back(?: [^>]+)?>(?:(?!</?back[ >]).)*</back>}{
$backcnt = $&;
while($backcnt =~ m{<ref(?: [^>]+)?>(?:(?!<ref[ >]).)*</ref>}igs){
$refcnt = $&;
$name = if($refcnt =~ m{<person-group(?: [^>]+)?>((?:(?!</?person-group[ >]).)*)</person-group>}is);
$year = if($refcnt =~ m{<year>((?:(?!</?year[ >]).)*)</year>}is);
$name =~ s{</?(?:string-name|surname|given-names)>}{}ig;
my $count = 1;
my $keys="$name $year\E$count";
if(exists ($sort{$keys})){
$keys =~ s{(\d)$}{my $icr=;$icr++;qq($icr)}e;
#print"$keys\n";
$sort{$keys}="$refcnt";
}
else
{
$sort{$keys}="$refcnt";
}
print join("\n",keys %sort);
}
qq($backcnt)
}igse;
my @keys = sort {
$sort{$a} <=> $sort{$b}
# or
# "\L$a" cmp "\L$b"
} keys %sort;
# print join("\n",@keys);
sub print_exit {
my $msg = shift;
#print "\n$msg";
exit;
}
谁能告诉我这里出了什么问题?
输入:
thieooieroh
apple
apple
highefhfe
bufghifeh
输出:
apple
apple
bufghifeh
highefhfe
thieooieroh
提前致谢。
通过非常简短地查看您的代码,您似乎希望将引用计数存储为散列中的值,并能够对单个键进行多次计数。这可以通过使用数组哈希(通常缩写为 HoA)轻松实现。根据定义,每个键必须是唯一的,但关联的值可以是一个引用,允许您在该键下存储多个项目,或者构建更复杂的数据结构。
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
my %hash;
while (my $line = <DATA>) {
chomp $line;
my ($key, $count) = split ',', $line;
push @{$hash{$key}}, $count;
}
for my $key (sort keys %hash) {
my $values = $hash{$key};
for (@$values) {
say "$key ($_)";
}
}
__DATA__
thieooieroh,1
apple,2
apple,3
highefhfe,4
bufghifeh,5
输出:
apple (2)
apple (3)
bufghifeh (5)
highefhfe (4)
thieooieroh (1)
如果你真的不关心每个键存储多个数据项,而只关心每个键出现的次数,那就更简单了。把上面代码中的两个循环改成:
while (my $line = <DATA>) {
chomp $line;
$hash{$line}++;
}
for my $key (sort keys %hash) {
say $key for 1 .. $hash{$key};
}
你得到了输出
apple
apple
bufghifeh
highefhfe
thieooieroh
至于您发布的其余代码,请勿尝试使用正则表达式解析 XML。任意 XML 不能 被 正则 表达式解析为超出非常粗略的第一近似值,因为 XML 在结构上不是 "regular". CPAN 上有许多很好的 XML 解析模块,它们可以为您正确解析您的 XML,同时与您尝试编写自己的解析器相比,您需要付出的努力要少得多。使用其中之一。不是正则表达式。
我需要使用 perl 对散列键进行排序,我还需要允许重复的键。所以我计划检查 perlexists
中的方法
如果它存在然后我增加最后一个数字然后我将存储到哈希中。
我尝试了以下代码:
use strict;
use warnings;
use iPerl::Basic qw(_save_file _open_file);
my $xml = $ARGV[0];
my ($xmlcnt,$backcnt,$refcnt,$name,$year) = "";
my %sort = ();
if(($#ARGV != 0) or(not -f "$xml") or($xml!~ m{\.xml$}i)){
print_exit("\t\tSYSTAX ERROR: <EXE> <xml File>\n\n")
};
$xmlcnt=_open_file($xml);
$xmlcnt =~ s{<back(?: [^>]+)?>(?:(?!</?back[ >]).)*</back>}{
$backcnt = $&;
while($backcnt =~ m{<ref(?: [^>]+)?>(?:(?!<ref[ >]).)*</ref>}igs){
$refcnt = $&;
$name = if($refcnt =~ m{<person-group(?: [^>]+)?>((?:(?!</?person-group[ >]).)*)</person-group>}is);
$year = if($refcnt =~ m{<year>((?:(?!</?year[ >]).)*)</year>}is);
$name =~ s{</?(?:string-name|surname|given-names)>}{}ig;
my $count = 1;
my $keys="$name $year\E$count";
if(exists ($sort{$keys})){
$keys =~ s{(\d)$}{my $icr=;$icr++;qq($icr)}e;
#print"$keys\n";
$sort{$keys}="$refcnt";
}
else
{
$sort{$keys}="$refcnt";
}
print join("\n",keys %sort);
}
qq($backcnt)
}igse;
my @keys = sort {
$sort{$a} <=> $sort{$b}
# or
# "\L$a" cmp "\L$b"
} keys %sort;
# print join("\n",@keys);
sub print_exit {
my $msg = shift;
#print "\n$msg";
exit;
}
谁能告诉我这里出了什么问题?
输入:
thieooieroh
apple
apple
highefhfe
bufghifeh
输出:
apple
apple
bufghifeh
highefhfe
thieooieroh
提前致谢。
通过非常简短地查看您的代码,您似乎希望将引用计数存储为散列中的值,并能够对单个键进行多次计数。这可以通过使用数组哈希(通常缩写为 HoA)轻松实现。根据定义,每个键必须是唯一的,但关联的值可以是一个引用,允许您在该键下存储多个项目,或者构建更复杂的数据结构。
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
my %hash;
while (my $line = <DATA>) {
chomp $line;
my ($key, $count) = split ',', $line;
push @{$hash{$key}}, $count;
}
for my $key (sort keys %hash) {
my $values = $hash{$key};
for (@$values) {
say "$key ($_)";
}
}
__DATA__
thieooieroh,1
apple,2
apple,3
highefhfe,4
bufghifeh,5
输出:
apple (2)
apple (3)
bufghifeh (5)
highefhfe (4)
thieooieroh (1)
如果你真的不关心每个键存储多个数据项,而只关心每个键出现的次数,那就更简单了。把上面代码中的两个循环改成:
while (my $line = <DATA>) {
chomp $line;
$hash{$line}++;
}
for my $key (sort keys %hash) {
say $key for 1 .. $hash{$key};
}
你得到了输出
apple
apple
bufghifeh
highefhfe
thieooieroh
至于您发布的其余代码,请勿尝试使用正则表达式解析 XML。任意 XML 不能 被 正则 表达式解析为超出非常粗略的第一近似值,因为 XML 在结构上不是 "regular". CPAN 上有许多很好的 XML 解析模块,它们可以为您正确解析您的 XML,同时与您尝试编写自己的解析器相比,您需要付出的努力要少得多。使用其中之一。不是正则表达式。