我在我的脚本中使用“=〜”来比较两个字符串(两个字符串的长度相同。)以允许不关心条件。如果一个角色是“。”在字符串中,忽略该字符进行比较。换句话说,它是部分匹配的情况。
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”可能有帮助?
答案 0 :(得分:7)
这不是perl版本问题。你正在进行正则表达式匹配。 =~
左侧的操作数是字符串,右侧的操作数是应用于它的正则表达式。
这可以用于您正在进行的部分匹配,因为字符串长度相同,正则表达式的每个字符都与字符串的字符匹配,但仅限于.
的位置在右边。如果正则表达式中有1
或0
($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将为额外字符生成30
,31
或2E
。
以下是快速解决方案。当大多数字符串不匹配时它会表现最佳(因为一旦匹配不可能就停止检查)。
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";
}