|
像 $1, $2 这样的 有点难以管理,比如下面的例子可以说明这一点:
[code=perl]#!/usr/bin/perl
use 5.010;
my $names = "Tom or Cat";
if ( $names =~ m/(\w+) (and|or) (\w+)/) {
say "I saw $1 and $2";
}[/mw_shl_code]
运行输出:# ./named.pl
I saw Tom and or 这里 (and | or) 可以匹配两种情况,要么 and 要么 or 都是可以的。
从输出可以看到,$1 存放了 Tom,$2 则存放了 or ---- 但是这时候,我们也许很希望 $2 里存放的是 Cat 。所以,我们可以使用 来达到这一目的:只要修改 为 即可。
更进一步来说,如果 Tom 和 Cat 这两个匹配能够放在一个有名称的变量里,那就更好记忆了。从 Perl 5.10 开始引入了正则表达式命名捕捉的概念。现在,捕捉的结果会放在一个特殊的哈希 %+ 里,其中的键就是捕捉时使用的特殊标签,而值则是被捕获到的字符串。给捕获的串添加标签的方法是使用 (?<LABEL>PATTERN) 这样的写法格式:
[code=perl]#!/usr/bin/perl
use 5.010;
my $names = "Tom or Cat";
if ( $names =~ m/((?<name1>\w+) (?:and|or) (?<name2>\w+))/) {
say "I saw $+{name1} and $+{name2}";
}[/mw_shl_code]
运行输出:# ./named.pl
I saw Tom and Cat 此时,匹配的字串 Tom 和 Cat 已经保存到了 name1 和 name2 里面了。注意对这两个变量的使用格式,前面的 '+' 号表示的是一个特殊的哈希表。
在使用捕捉标签后,反向引用也有了更新的必要,因为反向引用也是使用 \1, \2 (或 \g{1}, \g{2})这样的格式,现在可以使用 \g{label} 这样的写法了:
[code=perl]#!/usr/bin/perl
use 5.010;
my $names = "groad net groad";
if ( $names =~ m/(?<name1>\w+) net \g{name1}/) {
say "I saw $+{name1}";
}[/mw_shl_code]
运行输出:另外,还可以用 \k<label> 这种形式来替代 \g{label}。 |
|