在Perl正则表达式替换中使用$ 1 vs\1有什么区别?

Mr *_*Bar 11 regex perl

我正在调试一些代码,并想知道Perl正则表达式替换中$ 1和\ 1之间是否存在任何实际差异

例如:

my $package_name = "Some::Package::ButNotThis";

$package_name =~ s{^(\w+::\w+)}{$1};  

print $package_name; # Some::Package
Run Code Online (Sandbox Code Playgroud)

以下这一行似乎功能相同:

$package_name =~ s{^(\w+::w+)}{\1};
Run Code Online (Sandbox Code Playgroud)

这两个陈述之间是否存在细微差别?它们在不同版本的Perl中表现不同吗?

Sin*_*nür 14

首先,在开发时应始终使用警告:

#!/usr/bin/perl

use strict; use warnings;

my $package_name = "Some::Package::ButNotThis";

$package_name =~ s{^(\w+::\w+)}{\1};

print $package_name, "\n";
Run Code Online (Sandbox Code Playgroud)

输出:

\1 better written as $1 at C:\Temp\x.pl line 7.

当您收到不明白的警告时,请添加诊断信息:

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";
Run Code Online (Sandbox Code Playgroud)

输出:

C:\Temp> x
]
[9]

如果这不澄清,请看看:

C:\Temp> x | xxd
0000000: 5b08 5d0d 0a5b 395d 0d0a                 [.]..[9]..

另见perlop:

以下转义序列可用于插值和音译中的构造...

\10八进制是8十进制的.因此,替换部分包含字符代码BACKSPACE.

NB

顺便说一句,你的代码没有做你想做的事情:也就是说,它不会打印Some::Package一些与你的评论相反的软件包,因为你所做的只是Some::PackageSome::Package没有触摸的情况下替换::ButNotThis.

你可以这样做:

($package_name) = $package_name =~ m{^(\w+::\w+)};
Run Code Online (Sandbox Code Playgroud)

要么

$package_name =~ s{^(\w+::\w+)(?:::\w+)*\z}{$1};
Run Code Online (Sandbox Code Playgroud)


Eug*_*ash 8

来自perldoc perlre:

包围构造"(...)"创建捕获缓冲区.要在稍后的同一模式中引用缓冲区的当前内容,请使用\ 1表示第一个,\ 2表示第二个,依此类推.在比赛之外使用"$"而不是"\".

\<digit>符号在比赛之外的某些情况下有效.但它可能与八角形逃脱冲突.当反斜杠后跟超过1位数时会发生这种情况.