曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 3452|回复: 0
打印 上一主题 下一主题

将捕获的匹配放在变量中(特殊哈希 %+)

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2011-9-29 14:33:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
像 $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 。所以,我们可以使用
关闭捕获功能
来达到这一目的:只要修改
(andor)
(?:andor)
即可。

更进一步来说,如果 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]

运行输出:
# ./named.pl
I saw groad
另外,还可以用 \k<label> 这种形式来替代 \g{label}。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-4 00:01 , Processed in 0.078375 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表