首页 > 解决方案 > 在 perl 中,为什么 push 会导致 qr 创建的正则表达式在未放入双引号时被更改?

问题描述

我在脚本中定义正则表达式,使用qr并将它们推送到数组中。但现在看来,如果我不将正则表达式放在双引号内,将它推到数组上的操作会改变它。例子:

#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper qw(Dumper);
use Data::Dumper::Concise;
my @regexes;
my $rgx = 'dog'; my $mdf = 'i';
$rgx = join ( '', '(?', $mdf, ')', $rgx ) if ($mdf); # in production, $mdf could be empty
eval { $rgx = qr/$rgx/ };
if ($@) # catch illegitimate regex modifier, such as 'g'
{
   die "rgx==$rgx; mdf==$mdf; qr throws an error";
}
push @regexes, $rgx;
push @regexes, "$rgx";
print "first try just printing \$rgx\n";
print " no double quotes:";
print $rgx; print "\n";
print "yes double quotes:";
print "$rgx"; print "\n";
print "but now see what happens when I push it onto an array\n";
print Dumper \@regexes;

这会产生什么:

first try just printing $rgx
 no double quotes:(?^:(?i)dog)
yes double quotes:(?^:(?i)dog)
but now see what happens when I push it onto an array
[
  qr/(?i)dog/i,
  "(?^:(?i)dog)"
]

我认为这(?^:(?i)dog)是一个成品,准备好进行正则表达式匹配,例如

if ( /$rgx/ )

而且,事实上,这就是为什么我通过qr.

为什么要push改变它?

为什么它会产生特定的语法 qr/(?i)dog/i

标签: arraysregexperlpush

解决方案


您实际上是在询问返回的值之间的差异

my $rgx = qr/$rgx/; $rgx

my $rgx = qr/$rgx/; "$rgx"

qr//编译提供的正则表达式模式并返回一个表示编译形式的对象。这是存储在变量中的值$rgx,由表达式返回$rgx

""构建一个字符串,因此"$rgx"提供$rgx. 幸运的是,这会返回一个字符串,该字符串可用作编译对象表示的正则表达式模式。但是,通过这样做"$rgx",您实际上是在撤消由 完成的工作qr/$rgx/

Data::Dumper 使用文字表示正则表达式对象,使用qr//文字表示字符串""


推荐阅读