我有一个人们从中订购物品的地方数据库。我解析了列表以获得城市和州,所以它打印像这样 - 城市,州(纽约,纽约)等....
我使用变量$ city和$ state但是我想计算每个城市和州发生的次数所以看起来像这样 - 城市,州,伯爵(西雅图,华盛顿州8)
除了计数之外,我所有的工作都在运行..我正在使用哈希,但我无法弄清楚这个哈希有什么问题:
if ($varc==3) {
$line =~ /(?:\>)(\w+.*)(?:\<)/;
$city = $1;
}
if ($vars==5) {
$line =~ /(?:\>)((\w+.*))(?:\<)/;
$state = $1;
# foreach $count (keys %counts){
# $counts = {$city, $state} {$count}++;
# print $counts;
# }
print "$city, $state\n";
}
foreach $count (keys %counts){
$counts = {$city, $state} {$count}++;
print $counts;
}
答案 0 :(得分:1)
您可以建立一个&#34;位置&#34;而不是打印城市和州。两个项目的字符串,并使用以下计数代码:
# Declare this variable before starting to parse the locations.
my %counts = ();
# Inside of the loop that parses the city and state, let's assume
# that you've got $city and $state already...
my $location = "$city, $state";
$counts{$location} += 1;
}
# When you've processed all locations then the counts will be correct.
foreach $location (keys %counts) {
print "OK: $location => $counts{$location}\n";
}
# OK: New York, NY => 5
# OK: Albuquerque, NM => 1
# OK: Los Angeles, CA => 2
答案 1 :(得分:1)
这将是答案和代码审查的混合。我会从警告开始。
您正尝试使用正则表达式解析看起来像XML的内容。虽然this can be done,it should probably not be done。改为使用现有的解析器。
我怎么知道?尖括号之间的东西看起来像格式是XML,除非你有一个非常奇怪的CSV文件。
# V V
$line =~ /(?:\>)(\w+.*)(?:\<)/;
另请注意,您无需转义<
和>
,它们在正则表达式中没有特殊含义。
现在你的代码。
首先,请确保始终use strict
和use warnings
,以便您了解出错的内容。我可以告诉你不是因为你的循环中的$count
没有my
。
什么是$vars
(带有s
),什么是$varc
(带有c
)。我猜这与 s tate和 c 有关。是列号吗?在XML文件中?咦。
$line =~ /(?:\>)((\w+.*))(?:\<)/;
为什么有两个捕获组,都捕获相同的东西?
无论如何,您想要计算州和城市的每个组合发生的频率。
foreach $count (keys %counts){ $counts = {$city, $state} {$count}++; print $counts; }
您运行此代码吗?即使没有strict
,它也会出现语法错误。我甚至不确定它应该做什么,所以我不能告诉你如何解决它。
要实现计数,您需要一个哈希值。你得到了那个部分。但是你需要在文件读取循环之外声明该哈希变量。然后,您需要在哈希中为您的城市和州组合创建一个键,并在每次看到该组合时递增它。
my %counts; # declare outside the loop
while ( my $line = <$fh> ) {
chomp $line;
if ( $varc == 3 ) {
$line =~ /(?:\>)(\w+.*)(?:\<)/;
$city = $1;
}
if ( $vars == 5 ) {
$line =~ /(?:\>)((\w+.*))(?:\<)/;
$state = $1;
print "$city, $state\n";
$count{"$city, $state"}++; # increment when seen
}
}
您必须先解析整个文件,然后才能知道每个组合在文件中的频率。因此,如果要将这些打印在一起,则必须在读取文件的循环之外移动打印,并在稍后通过键迭代%count
散列。
my %counts; # declare outside the loop
while ( my $line = <$fh> ) {
chomp $line;
if ( $varc == 3 ) {
$line =~ /(?:\>)(\w+.*)(?:\<)/;
$city = $1;
}
if ( $vars == 5 ) {
$line =~ /(?:\>)((\w+.*))(?:\<)/;
$state = $1;
$count{"$city, $state"}++; # increment when seen
}
}
# iterate again to print final counts
foreach my $item ( sort keys %counts ) {
print "$item $counts{$item}\n";
}