繁体   English   中英

如何使用Perl检查标量中是否包含已编译的正则表达式?

[英]How do I check if a scalar has a compiled regex in it with Perl?

假设我有一个子程序/方法,用户可以调用它来测试一些数据(例如)可能如下所示:

sub test_output {
    my ($self, $test) = @_;
    my $output = $self->long_process_to_get_data();
    if ($output =~ /\Q$test/) {
        $self->assert_something();
    }
    else {
        $self->do_something_else();
    }
}

通常, $test是一个字符串,我们在输出中的任何地方寻找。 这是一个界面,使调用非常容易。 然而,我们发现有时候,直线串是有问题的 - 例如,一个大的,可能不同数量的空间......一个模式,如果你愿意的话。 因此,我想让他们作为一个选项传递正则表达式。 我可以这样做:

$output =~ $test

如果我可以假设它总是一个正则表达式,但啊,但向后兼容! 如果它们传入一个字符串,它仍然需要像原始字符串一样测试它。

那么在这种情况下,我需要测试以查看$test是否是正则表达式。 是否有任何良好的工具来检测标量是否有编译的正则表达式?

正如霍布斯指出的那样 ,如果您确定自己将使用5.10或更高版本,则可以使用内置支票:

 use 5.010;
 use re qw(is_regexp);
 if (is_regexp($pattern)) {
     say "It's a regex";
 } else {
     say "Not a regex";
 }

但是,我并不总是有这个选择。 一般来说,我通过使用ref检查原型值来做到这一点:

 if( ref $scalar eq ref qr// ) { ... }

我开始这样做的原因之一是我永远不会记住正则表达式引用的类型名称。 我现在甚至都记不住了。 它也不像其他部分那样大写,因为它实际上是perl源代码中实现的一个包(如果你想看到它,则在regcomp.c中 )。

如果你必须这么做,你可以使用你最喜欢的常量创建者使原型值保持不变:

 use constant REGEX_TYPE => ref qr//;

我在Effective Perl Programming中详细讨论了这个问题,作为“项目59:将值与原型进行比较”。

如果您想以两种方式尝试,可以在perl上使用版本检查:

 if( $] < 5.010 ) { warn "upgrade now!\n"; ... do it my way ... }
 else             { ... use is_regex ... }

从perl 5.10.0开始,有一种直接的,非棘手的方法:

use 5.010;
use re qw(is_regexp);
if (is_regexp($pattern)) {
    say "It's a regex";
} else {
    say "Not a regex";
}

is_regexp使用与perl相同的内部测试,这意味着与ref不同,如果由于某种奇怪的原因,你决定将正则表达式对象加入Regexp以外的类中(是的,这是可能的),它不会被愚弄。

在将来(或者现在,如果您可以发送具有5.10.0要求的代码),这应该被视为问题的标准答案。 不仅因为它避免了棘手的边缘情况,而且因为它具有准确说出其含义的优势。 富有表现力的代码是件好事。

请参阅内置的ref

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM