问题描述
我正在调试一些代码,想知道 Perl 正则表达式替换中 $1 和 \1 之间是否有任何实际区别
I'm debugging some code and wondered if there is any practical difference between $1 and \1 in Perl regex substitutions
例如:
my $package_name = "Some::Package::ButNotThis";
$package_name =~ s{^(\w+::\w+)}{$1};
print $package_name; # Some::Package
以下这行在功能上是等效的:
This following line seems functionally equivalent:
$package_name =~ s{^(\w+::w+)}{\1};
这两个陈述之间是否存在细微差别?它们在不同版本的 Perl 中的行为是否不同?
Are there subtle differences between these two statements? Do they behave differently in different versions of Perl?
推荐答案
首先,您应该始终使用 warnings 开发时:
First, you should always use warnings when developing:
#!/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:
When you get a warning you do not understand, add 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 个以上的反向引用时效果更好?下面是一个例子:
Why does it work better when there are more than 9 backreferences? Here is an example:
#!/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代码>
.
\10
octal is 8
decimal. So, the replacement part contained the character code for BACKSPACE
.
顺便说一下,你的代码没有做你想要的:也就是说,它不会不打印 Some::Package
一些包,这与你的评论所说的相反,因为你所有的正在做的是用 Some::Package
替换 Some::Package
而不触及 ::ButNotThis
.
Incidentally, your code does not do what you want: That is, it will not print Some::Package
some package contrary to what your comment says because all you are doing is replacing Some::Package
with Some::Package
without touching ::ButNotThis
.
你可以这样做:
($package_name) = $package_name =~ m{^(\w+::\w+)};
或
$package_name =~ s{^(\w+::\w+)(?:::\w+)*\z}{$1};
这篇关于在 Perl 正则表达式替换中使用 $1 和 \1 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!