我今天好像很傻,或者我有一个非常奇怪的问题.请考虑以下代码:
#!/usr/bin/perl use strict; use warnings; use warnings::unused; use warnings FATAL => 'uninitialized'; my ($String,$Pattern); $Pattern = "pattern"; $String = "pattern\n"; 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.这取决于模式.
$<digits> ($1,$2,...) Contains the subpattern from the corresponding set of capturing parentheses from the last successful pattern match [...]