我正在调试一些代码,并想知道Perl正则表达式替换中$ 1和\ 1之间是否存在任何实际差异
例如:
my $package_name = "Some::Package::ButNotThis";
$package_name =~ s{^(\w+::\w+)}{$1};
print $package_name; # Some::Package
以下这一行看起来功能相同:
$package_name =~ s{^(\w+::w+)}{\1};
这两个陈述之间是否存在细微差别?它们在不同版本的Perl中表现不同吗?
答案 0 :(得分:14)
首先,在开发时应始终使用warnings:
#!/usr/bin/perl
use strict; use warnings;
my $package_name = "Some::Package::ButNotThis";
$package_name =~ s{^(\w+::\w+)}{\1};
print $package_name, "\n";
输出:
\1 better written as $1 at C:\Temp\x.pl line 7.
当您收到不明白的警告时,请添加diagnostics:
C:\Temp> perl -Mdiagnostics x.pl \1 better written as $1 at x.pl line 7 (#1) (W syntax) Outside of patterns, backreferences live on as variables. The use of backslashes is grandfathered on the right-hand side of a substitution, but stylistically it's better to use the variable form because other Perl programmers will expect it, and it works better if there are more than 9 backreferences.
当有超过9个反向引用时,为什么它会更好?这是一个例子:
#!/usr/bin/perl
use strict; use warnings;
my $t = (my $s = '0123456789');
my $r = join '', map { "($_)" } split //, $s;
$s =~ s/^$r\z/\10/;
$t =~ s/^$r\z/$10/;
print "[$s]\n";
print "[$t]\n";
输出:
C:\Temp> x ] [9]
如果这不清楚,请查看:
C:\Temp> x | xxd 0000000: 5b08 5d0d 0a5b 395d 0d0a [.]..[9]..
另见perlop:
以下转义序列可用于插值和音译的构造......
\10
八进制是8
十进制。因此,替换部分包含BACKSPACE
的字符代码。
顺便提一下,你的代码没有按照你想要的那样做:也就是说,它会不打印Some::Package
某个包与你的评论所说的相反,因为你所做的就是替换{{ 1}} Some::Package
,但未触及Some::Package
。
您可以这样做:
::ButNotThis
或
($package_name) = $package_name =~ m{^(\w+::\w+)};
答案 1 :(得分:8)
包围构造“(...)”创建捕获缓冲区。参考 稍后在同一模式内使用缓冲区的当前内容 \ 1为第一个,\ 2为第二个,依此类推。在比赛之外使用 “$”而不是“\”。
\<digit>
符号在匹配之外的某些情况下有效。但它可能与八角形逃脱冲突。当反斜杠后跟超过1位数时会发生这种情况。