分组,捕获及后向引用

-- 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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于正则表达式的冷知识,我可以和你分享一些。 1. 分组捕获正则表达式中,可以使用括号来创建一个分组,并且可以通过在模式中使用反向引用引用这些分组。比如说,如果你想要匹配一个由两个连续的相同单词组成的字符串,可以使用分组捕获来实现,如下所示: ```python import re pattern = r'(\b\w+\b) \1' text = 'hello hello world' match = re.search(pattern, text) print(match.group(0)) # 'hello hello' print(match.group(1)) # 'hello' ``` 在这个例子中,`(\b\w+\b)` 匹配一个单词,并将其捕获到第一个分组中。然后,`\1` 引用了第一个分组,表示匹配与第一个分组相同的文本。因此,模式 `(\b\w+\b) \1` 匹配了两个相邻的相同单词。 2. replace()的用法 在 Python 中,可以使用 `re.sub()` 函数来进行正则表达式替换。这个函数接受三个参数:正则表达式模式、替换文本和原始文本。例如,下面的代码将替换文本中的所有数字为 `X`: ```python import re pattern = r'\d+' text = 'I have 3 apples and 2 oranges' replacement = 'X' new_text = re.sub(pattern, replacement, text) print(new_text) # 'I have X apples and X oranges' ``` 在这个例子中,`r'\d+'` 匹配一个或多个数字,然后使用 `re.sub()` 函数将其替换为 `X`。注意,这个函数不会修改原始文本,而是返回一个新的字符串。如果你想要在原始文本中进行替换,需要将其赋值给一个新的变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值