Chinaunix

标题: 请教一个关于hash的问题 [打印本页]

作者: Ammon    时间: 2011-11-18 13:32
标题: 请教一个关于hash的问题
有这样的一个数据结构:

grp "hardware" {
12/24;
13/25;
14/26;
};
grp "software" {
15/27;
16/28;
17/29;
};

想以"hardware""software"作为key值,然后对应的{安装数量/总数量}里面的"安装数量"作为values值.

尝试过把\r\n 替换掉合并成一行再使用正则匹配,但好像在多个{}情况下,很难匹配到.

所以请教下这个结构 怎么匹配成hash方式呢?
作者: kk861123    时间: 2011-11-18 14:13
回复 1# Ammon


    按你要求,写了一个
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %hash;
  5. my $key;
  6. while (<DATA>) {
  7.         if (/grp \"(\w+)\" \{/) {
  8.                 $key = $1;
  9.                 next;
  10.         }
  11.         if (/\};/) {
  12.                 undef $key;
  13.         }
  14.         if ($key) {
  15.                 push @{ $hash{$key} },(split /\//,$_)[0];
  16.         }
  17. }
  18. use Data::Dumper;
  19. print Dumper \%hash;

  20. __DATA__
  21. grp "hardware" {
  22. 12/24;
  23. 13/25;
  24. 14/26;
  25. };
  26. grp "software" {
  27. 15/27;
  28. 16/28;
  29. 17/29;
  30. };
复制代码

作者: Ammon    时间: 2011-11-18 14:21
本帖最后由 Ammon 于 2011-11-18 14:25 编辑

谢谢了 代码很简洁 完全符合需求

可以帮忙再解释下

push @{ $hash{$key} },(split /\//,$_)[0];

这个[0] 是什么意思吗?
作者: kk861123    时间: 2011-11-18 14:41
回复 3# Ammon


    split后数组的第一个元素,就是你要的‘安装数量’:
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;

  5. my $line = '12/24;';
  6. my @data = split /\//,$line;
  7. print Dumper \@data;
复制代码

作者: yinyuemi    时间: 2011-11-18 14:47
本帖最后由 yinyuemi 于 2011-11-18 14:55 编辑

回复 1# Ammon
  1. echo 'grp "hardware" {
  2. 12/24;
  3. 13/25;
  4. 14/26;
  5. };
  6. grp "software" {
  7. 15/27;
  8. 16/28;
  9. 17/29;
  10. };' |\
  11. perl -MData::Dumper -le 'while(<>){
  12.   if(/{/)
  13.     {$key=(split /"/)[1];}
  14.   elsif(/[0-9];$/)
  15.    {$value.=(split /\/|;/)[1]."\n"}
  16. else
  17.   {$hash{$key}=$value;$key=$value=""}
  18. }
  19. END{print Dumper \%hash}
  20. '
  21. $VAR1 = {
  22.           'software' => '27
  23. 28
  24. 29
  25. ',
  26.           'hardware' => '24
  27. 25
  28. 26
  29. '
  30.         };

复制代码

作者: kk861123    时间: 2011-11-18 15:10
回复 1# Ammon


    刚才一直没想起来范围操作符的使用方式,这样也比较好懂:
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %hash;
  5. my $key;
  6. while (<DATA>) {
  7.         if (/grp \"(\w+)\" \{/../\};/) {
  8.                 $key = $1;
  9.                 if (/(\d+)\/\d+/) {
  10.                         push @{$hash{$key}},$1;
  11.                 }
  12.         }
  13. }

  14. use Data::Dumper;
  15. print Dumper \%hash;

  16. __DATA__
  17. grp "hardware" {
  18. 12/24;
  19. 13/25;
  20. 14/26;
  21. };
  22. grp "software" {
  23. 15/27;
  24. 16/28;
  25. 17/29;
  26. };
复制代码





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2