字符串的部分匹配,运算符(=〜)

时间:2018-01-23 06:53:49

标签: regex string perl compare

我在我的脚本中使用“=〜”来比较两个字符串(两个字符串的长度相同。)以允许不关心条件。如果一个角色是“。”在字符串中,忽略该字符进行比较。换句话说,它是部分匹配的情况。

comp_test.pl:

#!/usr/bin/perl 

use strict;
use warnings;

my $a=".0.0..0..1...0..........0...0......010.1..........";
my $b="10.0..0..1...0..........0...0......010.1..........";
my $c=".0.0..0..1...0..........0...0......010.1..........";

if ($a =~ $b) {
print "a and b same\n";
}

if ($a =~ $c) {
print "a and c same\n";
}

由于“。”不关心条件,预期结果应该是“a和b相同”和“a和c相同”。但是,目前,结果只是“a和c相同”。请告诉我任何好的操作员或更改“。” “x”可能有帮助?

3 个答案:

答案 0 :(得分:7)

这不是perl版本问题。你正在进行正则表达式匹配。 =~左侧的操作数是字符串,右侧的操作数是应用于它的正则表达式。

这可以用于您正在进行的部分匹配,因为字符串长度相同,正则表达式的每个字符都与字符串的字符匹配,但仅限于.的位置在右边。如果正则表达式中有10$b的情况下为$a =~ $b),则字符串中必须存在完全匹配的字符({{ 1}}),而不是$a

要进行您似乎想要做的部分匹配,您可以使用按位异或,如下所示:

.

答案 1 :(得分:2)

.匹配1(或任何其他字符),1.(或1以外的任何其他字符)不匹配。

以下是快速解决方案。它在大多数字符串匹配时表现最佳(因为它总是检查整个字符串)。

sub is_match { ( ( $_[0] ^ $_[1] ) =~ tr/\x00\x1E\x1F//c ) == 0 }

say is_match($a, $b) ? "match" : "no match";
say is_match($b, $c) ? "match" : "no match";

工作原理:

    Hex of characters
    =================

    30 30 31 31 2E 2E  "0011.."
    30 31 30 31 30 31  "010101"
XOR -----------------
    00 01 01 00 1E 1F
       ^^ ^^           2 mismatches

如果其中一个字符串比另一个字符串短,则此解决方案甚至可以工作(因为XOR将为额外字符生成30312E

以下是快速解决方案。当大多数字符串不匹配时它会表现最佳(因为一旦匹配不可能就停止检查)。

sub make_matcher {
   my $pat =
      join '',
         map { $_ eq '.' ? $_ : "[.\Q$_\E]" }
            split //, $_[0];

   return qr/^$pat\z/;
}

sub is_match { $_[0] =~ make_matcher($_[1]) }

say is_match($a, $b) ? "match" : "no match";
say is_match($b, $c) ? "match" : "no match";

测试。

答案 2 :(得分:-4)

根据我的理解,你试图比较2个字符串的长度。基本上,只需要比较sting的长度,而不是比特字符。

my $a=".0.0..0..1...0..........0...0......010.1..........";
my $b="10.0..0..1...0..........0...0......010.1..........";
my $c=".0.0..0..1...0..........0...0......010.1..........";

所以代码可以是:

if(length($a) == length($b))
{
  print "match found";
}
else
{
  print "No match";
}