Regex 哈希映射perl中字符串与键值对的比较

Regex 哈希映射perl中字符串与键值对的比较,regex,string,perl,hash,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 Worl

我在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\u至\u编号=( “你好,世界,我是XYZ”=>11, “我使用堆栈溢出进行指导”=>12, “编程很好!”=>13, );

因此,在上述情况下,str1和str2应该匹配 而str3则没有对手

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


让我知道这是否清除了用例

这可能很简单:

my ( $first_match ) = grep { s/\W//gr =~ m/\Q$transformed_match\E/i } keys %msg_to_number;
移除模式锚,如果
$transformed\u match
是(transformed)键的子字符串,则它将匹配

或者您可以将其反转-因此,如果键是子字符串,则它匹配:

#!/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%确定。但无论如何,这可能不是一个好主意!)

我不确定您想做什么,但似乎您需要一个三方匹配。如果使用REGXs,则需要确保匹配所有需要的案例,或者不匹配所有不需要的案例。下面的脚本可能更接近您需要的内容。它匹配(1)您的输入字符串,(2)您的哈希键,以及(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

你能举出一些应该和不应该匹配的例子吗?如果没有这个问题,很难回答这个问题。但是典型的技巧是-删除正则表达式上的模式锚,然后子字符串匹配将起作用-如中所述-在我给出的第一个示例中,没有锚,所以子字符串匹配。尼特:你说“假设所有键都是唯一的”。这里没有假设。它们必须是唯一的——这就是散列的定义@MattJacob:我的意思是说,你将要匹配的模式将是唯一的。添加了一个示例,说明什么应该匹配,什么没有问题。字符串
“你好,世界,我是XYZ!!!!!”!!!!!编程很好?当存在小写和大写差异时,此操作将失败。例如:你好,世界,我是xyz和ABC,在这种情况下,它将失败,但以前工作过。如果您可以在模式匹配中添加一些标志,使其不区分大小写就好了。类似于
i
的东西。这有什么作用?您正在将定义的字符串与哈希的输入和键进行匹配。那根绳子是从哪里来的?
   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