加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式 – 尽管检查了undef,但是关于未初始化变量的警告

发布时间:2020-12-14 06:06:20 所属栏目:百科 来源:网络整理
导读:我今天好像很傻,或者我有一个非常奇怪的问题.请考虑以下代码: #!/usr/bin/perluse strict;use warnings;use warnings::unused;use warnings FATAL = 'uninitialized';my ($String,$Pattern);$Pattern = "pattern";$String = "patternn";if (($String =~ m/
我今天好像很傻,或者我有一个非常奇怪的问题.请考虑以下代码:

#!/usr/bin/perl

use strict;
use warnings;
use warnings::unused;
use warnings FATAL => 'uninitialized';

my ($String,$Pattern);

$Pattern = "pattern";
$String = "patternn";

if (($String =~ m/^([^ ]+).*$/s) &&
    defined($1) &&
    ($1 =~ m/^.*$Pattern$/s)) {

  print $1."n";
}

此代码生成以下警告(然后因使用警告而停止FATAL =>’uninitialized’;):

Use of uninitialized value $1 in concatenation (.) or string at [...]

我真的不明白这一点,因为我在测试是否在使用它之前定义(初始化)$1.罪魁祸首似乎是最后的条件线(即($1 = ~m /^.*$Pattern $/ s)).如果我把它留下,警告就会消失.

但为什么?根据我的理解,该行应该只测试$1,但不改变它的值($Pattern和RegEx的其余部分不包含括号,因此不应该为$1重新分配可能的匹配).

嗯…在考虑它的时候,我想到Perl可能会在RegEx匹配的情况下设置$1及其同事,无论RegEx中是否有括号.这可以解释这种行为.这是真的吗?

解决方法

我在上面的评论中创建了一个答案:

if (($String =~ m/^([^ ]+).*$/s) && # If matching,this will set $1
    defined($1) &&                   # Here $1 is still defined
    ($1 =~ m/^.*$Pattern$/s)         # If matching,will reset all $1,.. vars
) {

因此,每当正则表达式匹配时,它将重置所有数字变量(以及其他正则表达式相关变量).

我看到的唯一解决方案是将条件分开并在额外变量中保存$1.无论如何,这通常是一件好事.

if ($String =~ m/^([^ ]+).*$/s and defined $1) {
    my $match = $1;
    if ($match =~ m/^.*$Pattern$/s) { ... }
}

请注意,在这种情况下,您甚至不必检查已定义的$1,因为如果此模式匹配,将始终定义$1.这取决于模式.

perldoc perlvar:

$<digits> ($1,$2,...)
        Contains the subpattern from the corresponding set of capturing
        parentheses from the last successful pattern match [...]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读