哈希映射perl

时间:2015-11-10 17:51:53

标签: regex string perl hash

我在Perl的哈希映射中有键值对。假设所有键都是唯一的。

例如:

my %msg_to_number = ( 
 'Hello World, I am XYZ'    => 11,
 'I am using Stack Overflow for Guidance'   => 12,
 'Programming is good!' => 13,
);

现在,如果我要比较的输入字符串是这样的:

str1 = Hello World, I am XYZ;
str2 = Hello World, I am XYZ and ABC;

所以下面的代码将str1正确映射到哈希映射键,但是 对于str2,它失败了。

我的问题是如何修改下面的代码以使其适用于两种情况。那就是:使代码也适用于str1和str2。对于str1和str2,哈希映射应返回11。这甚至是哈希映射中的关键字匹配字符串的一部分比较或完整字符串它应该返回匹配。 (我假设部分匹配的情况会发生在句子的开头用词进行比较,这简化了一些事情)

现在正下面的代码通过删除像!,#等字符进行比较,转换为小写然后匹配。

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

my %msg_to_number = ( 
 'Hello World, I am XYZ'    => 11,
 'I am using Stack Overflow for Guidance'   => 12,
 'Programming is good!' => 13,
);

my $str_to_match = 'Hello World, I am XYZ!!!!!';
my $transformed_match = $str_to_match =~ s/\W//gr;

my ( $first_match ) = grep { s/\W//gr =~ m/^\Q$transformed_match\E$/i } keys     
%msg_to_number;
print "$first_match   =  $msg_to_number{$first_match}\n";

我尝试使用正则表达式来代替上述代码,但无法使其正常工作。如果有人可以提出一些改变或不同的方法(建议)做同样的事情会很棒。 (代码正在进行的原始逻辑加上部分比较)。这是关于堆栈溢出的后续问题。

由于

更新: 什么应该匹配以及什么不匹配的示例。

假设下面的哈希映射:     我的%msg_to_number =(      'Hello World,我是XYZ'=> 11,      '我正在使用Stack Overflow for Guidance'=> 12,      “编程很好!” => 13,     );

str1 = Hello World, I am XYZ
str2 = Hello World
str3 = Hello World, I am XYZ, ABC and EFG.

所以在上面str1和str2应该匹配 而str3不匹配。

正如我所说,即使起始部分是部分匹配,它也应该匹配。

如果这样可以清除用例

,请告诉我

2 个答案:

答案 0 :(得分:0)

这可能很简单:

my ( $first_match ) = grep { s/\W//gr =~ m/\Q$transformed_match\E/i } keys %msg_to_number;

删除模式锚点,并且$transformed_match是(转换后的)键的子字符串,然后它匹配。

或者你可以反过来 - 所以如果是子字符串,它匹配:

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

my %msg_to_number = ( 
 'Hello World, I am XYZ'    => 11,
 'I am using Stack Overflow for Guidance'   => 12,
 'Programming is good!' => 13,
);

my $str_to_match = 'Hello World, I am XYZ and ABC!!!!!';
my $transformed_match = $str_to_match =~ s/\W//gr;

my ( $first_match ) = grep { my $tr_key = s/\W//gr; $transformed_match =~ m/$tr_key/i or $tr_key =~ m/$transformed_match/ } keys %msg_to_number;
print "$first_match   =  $msg_to_number{$first_match}\n";

(可能有一种方法可以在正则表达式中进行转换和匹配 - 我不是100%肯定。但无论如何它可能不是一个好主意!)

答案 1 :(得分:0)

我不确定你想做什么,但似乎你需要一个三方匹配。如果您使用REGX,则需要确保您匹配所需的所有案例,或者不匹配您不想要的所有案例。以下脚本可能更接近您的需要。它匹配(1)您的输入字符串,(2)您的HASH KEY,以及(3)您正在寻找的内容。

   use strict;
   use warnings;

   my %msg_to_number = ( 
    'Hello World, I am XYZ'                    => 11,
    'I am using Stack Overflow for Guidance'   => 12,
    'Programming is good!'                     => 13,
   );

   while(<DATA>)
   {
       chomp;
       foreach my $k (keys %msg_to_number)
       {
           print "$_, $msg_to_number{$k}\n" if $_ =~ /Hello World/ and $k =~ /Hello World/;
       }
   }
   exit(0);

   __DATA__
   Hello World
   Hello World, I am ABC
   I am using Stack Overflow for Guidance
   Programming is good
   Hello World, I am ABC, DEF, GHI

这是输出:

Hello World, 11
Hello World, I am ABC, 11
Hello World, I am ABC, DEF, GHI, 11