【问题标题】:Perl String Parsing to HashPerl 字符串解析为哈希
【发布时间】:2013-02-04 18:48:17
【问题描述】:

所以假设我有字符串。

 $my str = "Hello how are you today. Oh thats good I'm glad you are happy. Thats wonderful; thats fantastic."

我想创建一个哈希表,其中每个键都是唯一的单词,值是它在字符串中出现的次数,即我希望它是一个自动化的过程。

my %words {
  "Hello" => 1,
  "are" => 2,
  "thats" => 2,
  "Thats" => 1
  };

老实说,我是 PERL 的新手,不知道如何执行此操作,如何处理标点符号等。

更新:

还有,可以用吗

   split('.!?;',$mystring)   

不使用这种语法,但基本上以 .要么 !要么 ?等等..哦和''(空格)

【问题讨论】:

  • 你如何想要处理标点符号是个问题。 I'mI am 的副本,还是应该只是其自身的副本? ultra-complex 是否与 ultracomplex 重复?
  • 任何不同的东西都应该不同。我的意思是像 .'s !'s ;'s 和 ?'s 这样的标点符号。对不起。
  • 你会发现一些提示here

标签: string perl parsing hash


【解决方案1】:

这将使用空格来分隔单词。

#!/usr/bin/env perl
use strict;
use warnings;

my $str = "Hello how are you today."
        . " Oh thats good I'm glad you are happy."
        . " Thats wonderful. thats fantastic.";

# Use whitespace to split the string into single "words".
my @words = split /\s+/, $str;

# Store each word in the hash and count its occurrence.
my %hash;
for my $word ( @words ) {
    $hash{ $word }++;
}

# Show each word and its count. Using printf to align output.
for my $key ( sort keys %hash ) {
    printf "\%-10s => \%d\n", $key, $hash{ $key };
}

您需要进行一些微调才能获得“真实”的单词。

Hello      => 1
I'm        => 1
Oh         => 1
Thats      => 1
are        => 2
fantastic. => 1
glad       => 1
good       => 1
happy.     => 1
how        => 1
thats      => 2
today.     => 1
wonderful. => 1
you        => 2

【讨论】:

  • 他需要更多的分隔符而不仅仅是空格。看看我做了什么:my @strAry = split /[:,\.\s\/]+/, $str;
  • 这就是“需要一些微调”的目的。等待 homeworkoverflow.com,以便我可以在那里发布。 ;-)
  • @Perleone 所以对于 PERL,我可以在 {} 中放置一个变量,它只会将它添加到哈希中?那么如何访问变量呢?如果该变量已经在 Hash 中,会发生什么?
  • @Vlad 是的。 $hash{beer} = 5; 将带有值 5 的键 beer 添加到 %hash。你以同样的方式访问它:print $hash{beer}; 将输出5。如果密钥已经存在,则该值将被覆盖:$hash{beer} = 3;
  • 哦,好的。所以 ++ 只会在现值上加一?
【解决方案2】:

一种简单的方法是split 任何在您的视图中不是有效单词字符的字符上的字符串。请注意,这绝不是一个详尽的解决方案。我只取了一组有限的字符。

当您发现边缘情况时,您可以在括号 [ ... ] 内添加有效的单词字符。您也可以在 http://search.cpan.org 中搜索为此目的而设计的模块。

正则表达式[^ ... ] 表示匹配括号内的任何字符。 \pL 是更大的字母子集,而其他字母则是文字。破折号- 必须转义,因为它是字符类括号内的元字符。

use strict;
use warnings;
use Data::Dumper;

my $str = "Hello how are you today. Oh thats good I'm glad you are happy.
           Thats wonderful; thats fantastic.";
my %hash;
$hash{$_}++                      # increase count for each field
    for                          # in the loop
    split /[^\pL'\-!?]+/, $str;  # over the list from splitting the string 
print Dumper \%hash;

输出:

$VAR1 = {
          'wonderful' => 1,
          'glad' => 1,
          'I\'m' => 1,
          'you' => 2,
          'how' => 1,
          'are' => 2,
          'fantastic' => 1,
          'good' => 1,
          'today' => 1,
          'Hello' => 1,
          'happy' => 1,
          'Oh' => 1,
          'Thats' => 1,
          'thats' => 2
        };

【讨论】:

  • 好的,谢谢。我该如何解释那不应该是这样的事实。
  • @Vlad 你想区分大小写吗?然后将lc($_) 更改为$_。我会删除它。
  • 好的,谢谢。我将不得不努力学习这种语法。你的有错误吗?为什么一切都是红色的,即一个字符串?
  • @Vlad Red?你说的是stackoverflow的代码高亮吗?这只是单引号使它认为它是一个带引号的字符串。
  • 我想通了哈哈。感谢您的帮助!
【解决方案3】:

试试这个:

use strict;
use warnings;

my $str = "Hello, how are you today. Oh thats good I'm glad you are happy. 
           Thats wonderful.";
my @strAry = split /[:,\.\s\/]+/, $str;
my %strHash;

foreach my $word(@strAry) 
{
    print "\nFOUND WORD: ".$word;
    my $exstCnt = $strHash{$word};

    if(defined($exstCnt)) 
    {
        $exstCnt++;
    } 
    else 
    {
        $exstCnt = 1;
    }

    $strHash{$word} = $exstCnt;
}

print "\n\nNOW REPORTING UNIQUE WORDS:\n";

foreach my $unqWord(sort(keys(%strHash))) 
{
    my $cnt = $strHash{$unqWord};
    print "\n".$unqWord." - ".$cnt." instances";
}

【讨论】:

  • 为什么是双倍行距格式?您不必使用连接运算符来插入变量,只需将它们输入到字符串"Found word $word\n" 中即可。您不需要遍历转换变量来增加计数器,只需直接增加它。
  • @Pfoampile 所以对于 PERL,我可以在 {} 中放置一个变量,它只会将它添加到哈希中?那么如何访问变量呢?如果该变量已经在 Hash 中,会发生什么?
  • 是的,@Vlad。 $strHash{'Vlad'} = 1; 将键 'Vlad' 添加到哈希并为其分配值 1
  • @TLP,好点子。但我认为这种更冗长的方式更容易让我们的初学者弗拉德了解正在发生的事情
  • @foampile 你的解释非常彻底。我以前编程过,只是不是在 PERL 中,所以很容易遵循你的逻辑。谢谢:)
【解决方案4】:
 use YAML qw(Dump);
 use 5.010;

 my $str = "Hello how are you today. Oh thats good I'm glad you are happy. Thats wonderful; thats fantastic.";
 my @match_words = $str =~ /(\w+)/g;
 my $word_hash = {};
 foreach my $word (sort @match_words) {
     $word_hash->{$word}++;
 }
 say Dump($word_hash);
 # -------output----------
 Hello: 1
 I: 1
 Oh: 1
 Thats: 1
 are: 2
 fantastic: 1
 glad: 1
 good: 1
 happy: 1
 how: 1
 m: 1
 thats: 2
 today: 1
 wonderful: 1
 you: 2

【讨论】:

    猜你喜欢
    • 2012-10-12
    • 2014-07-10
    • 2019-04-04
    • 2012-02-22
    • 1970-01-01
    • 2017-01-06
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多