Bin*_*rus 4 regex perl initialization regex-group
我今天好像很傻,或者我有一个非常奇怪的问题.请考虑以下代码:
#!/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";
}
Run Code Online (Sandbox Code Playgroud)
此代码生成以下警告(然后因为而停止use warnings FATAL => 'uninitialized';):
Use of uninitialized value $1 in concatenation (.) or string at [...]
Run Code Online (Sandbox Code Playgroud)
我真的不明白这个,因为我正在测试是否$1在使用之前定义(初始化).罪魁祸首似乎是最后的条件线(即($1 =~ m/^.*$Pattern$/s)).如果我把它留下,警告就会消失.
但为什么?根据我的理解,该行应该只测试 $1,但不能更改其值($Pattern并且该RegEx的其余部分不包含括号,因此$1不应重新分配可能的匹配).
嗯......一边想着它,它在我脑海中是Perl可能设置$1及其同事每情况下,当一个正则表达式是匹配,是否有在正则表达式的括号内.这可以解释这种行为.这是真的吗?
包含来自上一次成功模式匹配的相应捕获括号集的子模式,不包括已经退出的嵌套块中匹配的模式.
由于第二个匹配是最后一次成功的模式匹配,因此if块内部$1是undef.
你可以这样做:
my ($match) = ($String =~ m/^([^\ ]+).*$/s);
if (defined $match && $match =~ m/^.*$Pattern$/s) {
print $match."\n";
}
Run Code Online (Sandbox Code Playgroud)
我在上面的评论中创建了一个答案:
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
) {
Run Code Online (Sandbox Code Playgroud)
因此,每当正则表达式匹配时,它将重置所有数字变量(以及其他正则表达式相关变量).
我看到的唯一解决方案是将条件分开并保存$1在一个额外的变量中.无论如何,这通常是一件好事.
if ($String =~ m/^([^\ ]+).*$/s and defined $1) {
my $match = $1;
if ($match =~ m/^.*$Pattern$/s) { ... }
}
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下,您甚至不必检查,defined $1因为如果此模式匹配,$1将始终定义.这取决于模式.
$<digits> ($1, $2, ...)
Contains the subpattern from the corresponding set of capturing
parentheses from the last successful pattern match [...]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
130 次 |
| 最近记录: |