我有一个非常简单的代码来解析文件名:
#!/usr/bin/env perl
use 5.040;
use warnings FATAL => 'all';
use autodie ':default';
my $string = '/home/con/bio.data/blastdb/phytophthora.infestans.KR_2_A2/GCA_012552325.1.protein.faa';
if ($string =~ m/blastdb\/(\w)\w+\.([\w\.]+)/) {
my $rest = $2; # $1 would be valid here
$rest =~ s/\./ /g;
my $name = "$1.$rest"; # $1 disappears here
}
上述代码失败Use of uninitialized value $1 in concatenation (.) or string
但是,如果我将其保存$1
到变量中,例如$g
,信息不会丢失。
if ($string =~ m/blastdb\/(\w)\w+\.([\w\.]+)/) {
my ($g, $rest) = ($1, $2);
$rest =~ s/\./ /g;
my $name = "$g.$rest";
}
所以我可以解决这个问题。
但是,$1
它不应该就这样消失吗?$1
在范围内不应该保持有效吗?这是 Perl 中的错误吗?还是我错过了https://perldoc.perl.org/perlretut中的某些规则?
$rest =~ s/\./ /g;
执行正则表达式匹配。它匹配的模式 (/\./
) 没有任何捕获组,因此在完成后所有捕获变量都未初始化。您可以将所需内容保存在变量中 — — 最简单的方法是执行
if (my ($g, $rest) = $string =~ /yadda yadda/)
或,您可以避免在完成前一个捕获之前执行其他正则表达式匹配 — — 在这种情况下,$rest =~ tr/./ /
可以像一样完成工作$rest =~ s/\./ /g
,但不会破坏捕获变量。