分组,捕获及后向引用

-- Start

我们在 括号及后向引用 一节中了解到了括号的两种用途:分组和捕获。

分组

事实上,正在表达式还一共提供了三种结构用于分组,如下:

元字符(Metacharacter) 匹配(Matches)
(...) 分组
(?:...) 分组
(?>…) 固化分组 

它们之间有什么区别呢? 我们先看一个例子吧。

#!/usr/bin/perl

my $testText = "#test#"; # 测试文本

# 基准
if($testText =~ m/#.*#/) {
	print "#.*# 匹配了 #test#\n";
}

# 测试 (...)
if($testText =~ m/(#.*#)/) {
	print "(#.*#) 匹配了 $1\n";
}

# 测试 (?:...)
if($testText =~ m/(?:#.*#)/) {
	print "(?:#.*#) 匹配了 $1\n";
}

# 测试 (?>...)
if($testText =~ m/(?>#.*#>)/) {
	print "(?>#.*#>) 匹配了 $1\n";
} else {
	print "(?>#.*#>) 无法匹配 #test#\n";
}

运行结果:

#.*# 匹配了 #test#
(#.*#) 匹配了 #test#
(?:#.*#) 匹配了
(?>#.*#>) 无法匹配 #test#

从结果中我们可以看出,(?:...) 只能用于分组,而 (...) 除了分组还捕获了括号中的内容。那 (?>...) 是什么意思呢?(?>#.*#>) 为什么无法匹配 #test# 呢?要想理解什么是固化分组,我们必须深入正则表达式的匹配原理,我们在 贪婪,非贪婪和占有量词的区别 一节中介绍了什么是 占有量词,如果你理解了什么是占有量词,那么肯定知道了为什么 (?>#.*#>) 无法匹配 #test#。

捕获和后向引用

我们知道了括号除了可以用于分组,还可以用于捕获。我们为什么要捕获括号中的内容呢? 主要原因是,在捕获之后,我们可以通过后向引用来得到之前捕获的内容,这在文本替换操作中非常重要,捕获及后项引用的形式如下:

元字符(Metacharacter) 匹配(Matches)
(...) 捕获
\n 引用第n个括号中匹配的内容
(?<name>...) 命名捕获

命名捕获的意思是给捕获的内容起个名字,稍后我们可以通过这个名字来引用其内容,而无需通过 \n 的形式来引用。Perl 和 Java 不支持命名捕获。

--更多参见:正则表达式精萃
-- 声 明:转载请注明出处
-- Last Updated on 2012-05-13
-- Written by ShangBo on 2012-05-13
-- End


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值