如何使用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是否是正则表达式.是否有任何良好的工具来检测标量是否有编译的正则表达式?

解决方法

作为 hobbs points out,如果您确定自己将使用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 ... }

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...