Perl 部分匹配 [英] Perl partial match

查看:46
本文介绍了Perl 部分匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑下面的脚本,即使 $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 函数区分大小写.如果您想要不敏感的匹配,请将 uclc 函数应用于两个参数.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆