Perl 部分匹配 [英] Perl partial match
问题描述
请考虑下面的脚本,即使 $b 是部分匹配,我也想将 $b 匹配到 $a.这能做到吗?
Please consider the script below, I want to match $b to $a even if $b is a partial match. Can this done be done?
$a="MCF-7";
$b="MCF";
if($b=~m/$a/i)
{
print "FOUND";
}
推荐答案
虽然正则表达式可以做到这一点,但听起来您的问题也可以用 index
函数解决:
While regular expressions can do this, it sounds like your problem could also be solved with the index
function:
say index($haystack, $needle) >= 0 ? 'match' : 'fail'; # any position
say index($haystack, $needle) == 0 ? 'match' : 'fail'; # anchored at start
index
函数区分大小写.如果您想要不敏感的匹配,请将 uc
或 lc
函数应用于两个参数.
The index
function is case sensitive. If you want an insensitive match, apply the uc
or lc
function to both arguments.
尽管 index
函数比正则表达式快得多,但如果您确实需要正则表达式解决方案,您可以构建一个正则表达式生成器,该生成器会产生一系列交替执行部分匹配.
Although the index
function will be much faster than a regex, if you do want a regex solution you can build a regex generator that produces a series of alternations that will perform partial matching.
sub build_partial {
my ($str, $min) = (@_, 1);
my @re;
for (0 .. length($str) - $min) {
my $str = substr $str, $_;
for ($min .. length $str) {
push @re, quotemeta substr $str, 0, $_
}
}
my $re = join '|' => sort {length $a <=> length $b} @re;
qr/^(?:$re)$/i
}
my $haystack = 'MCF-7';
my $needle = 'MCF';
my $regex = build_partial $haystack;
say $needle =~ /$regex/ ? 'match' : 'fail'; # match
为 MCF-7
生成的正则表达式如下所示:
The regex generated for MCF-7
looks like this:
/^(?:M|C|F|7|MC|CF|\-|MCF|F\-|\-7|CF\-|F\-7|MCF\-|CF\-7|MCF\-7)$/i
即使针是大海捞针中的单个字符,它也会匹配.build_partial
接受一个可选数字,指示匹配所需的最小长度:
And it will match even if the needle is a single character from the haystack. build_partial
takes an optional number indicating the minimum length required for a match:
my $regex_3 = build_partial $haystack, 3;
产生这个正则表达式:
/^(?:MCF|CF\-|F\-7|MCF\-|CF\-7|MCF\-7)$/i
这些模式匹配从任何位置开始的子字符串.如果您希望它锚定到字符串的前面,build_partial
会变得更简单:
These patterns match a substring starting from any position. If you want it anchored to the front of the string, build_partial
gets a bit simpler:
sub build_partial {
my ($str, $min) = (@_, 1);
my $re = join '|' => map {
quotemeta substr $str, 0, $_
} $min .. length $str;
qr/^(?:$re)$/i
}
这篇关于Perl 部分匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!