分组、反向引用和编号(命名)组

在正则表达式中,可以用一对(英文)圆括号创建一个分组。比如模式

([A-Z]+)(/d+)

[A-Z]+/d+

返回的匹配结果相同,但前者使用了两对圆括号分组还捕获了额外的两个子字符串。举例来说,如果用上面两个模式来测试字符串 ABC123,那么第二个模式会返回 ABC123(因为匹配成功),而第一个模式除了返回 ABC123 这个匹配项之外,还会捕获两个组,第一个组中包含 ABC,而第二个组中包含 123。这两个分组都是捕获组――即捕获匹配项中子字符串的组。

分组的作用表现在两方面。一是用在同一模式后续的组件中,称之为反向引用(back reference)。比如把上面第一个模式修改为

([A-Z]+)(/d+)/1

之后,就能够匹配 ABC123ABC、A8A、AB25AB 等等类似的字符串。这个修正后的模式中的 /1 就叫做反向引用,数字 1 表示引用模式中的第一个捕获组。也就是说,反向引用是在匹配模式中使用的一个概念(技术)。

反向引用比较典型的一个用法是匹配 XHTML 代码中成对出现的开、闭标签。比如,在 XHTML 中标题(<h1> 到 <h6>)元素有六个级别,如果你要匹配一个网页中所有级别的标题元素就会用到反向引用。相应的模式可能是(假设标题中的文本只包含文字而不包含标点符号):

<(h[1-6])>/w+<//1>

这个模式的含义就是匹配 < 字符后跟 h 字符,后跟 1 到 6 中的任何一个数字,后跟 > 字符,后跟一或多个文字字符序列,后跟 < 字符,后跟正斜杠字符 /,后跟与第一个捕获组相同的字符序列(如前面圆括号中是 h1 此处也必须是 h1),后跟 > 字符。此时,反向引用可以保证捕获的标题元素是完整的,即是像 <h1>……</h1> 或 <h3>……</h3> 这样完整的标签对儿。这种情况下,如果不使用反向引用,而使用 <h[1-6]>/w+</h[1-6]> 就会得到不对称的标签对儿,如 <h1>……</h3> 。

分组的另一个用途是在替换模式中引用,称之为编号(或命名)组。编号(命名)组的概念也是建立在匹配模式中的分组之上的。它与反向引用的区别在于,编号(命名)组是在替换模式中使用的一个概念(技术)。也就是说,编号(命名)组是在替换模式中引用匹配模式中分组的一种技术。比如,以模式

([A-Z]{3})(/d{2})

为例,该模式匹配 ABC12、DEF56 等等所有连续的三个大写字母字符后跟两个数字的字符序列。如果要在这些匹配的字符序列的字母与数字之间插入一个空格或者一个连字符作为分隔符,那么就可以在替换模式中使用编号组,比如:

$1-$2

其中 $1 包含与匹配模式中的组件 [A-Z]{3} 匹配的三个连续字母序列,而 $2 包含与 /d{2} 匹配的两个数字。而 $1 和 $2 之间的 – 就是一个直接量连字符。

至于命名组并不是所有正则表达式实现都支持,只有少数的编程语言如 C#、VB.NET 中才支持。所谓命名组,就是在匹配模式中定义分组时为每个组命名,C# 中的语法是

(?<组名>模式)

然后在替换模式中就可以使用“组名”来引用该组了,对应的语法是

${组名}

命名组优于编号组是因为它让人对替换模式中的引用更清楚、不致混淆。

综上所述,正则表达式中的分组是基础,反向引用和编号(命名)组是对相应分组的两种不同的引用方式――反向引用是在匹配(或者说同一个)模式中引用分组,而编号(命名)组则是在替换模式中引用分组

注:有时候也将在替换模式中使用的编号(命名)组称为反向引用。所以,可以认为无论是 /1 还是 $1 还是 ${date} ,只是因地制宜地使用了不同的形式而已,在本质上它们都是反向引用。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值