在 Perl 正则表达式替换中使用 $1 和 \1 有什么区别? [英] What is the difference between using $1 vs \1 in Perl regex substitutions?

查看:102
本文介绍了在 Perl 正则表达式替换中使用 $1 和 \1 有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调试一些代码,想知道 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:

以下转义序列可用于插入和音译的结构中…

The following escape sequences are available in constructs that interpolate and in transliterations …

\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 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆