正则表达式反向引用

来源于:http://searun.javaeye.com/blog/389186;

使用后向引用匹配 在后面将会重新来看上面的例子。现在我们来看一个简单的例子,一个如果不使用后向引用就不能解决问题的例子。 假设现在有一段文本,你希望找到所有重复的单词(笔误使得单词出现了两次)。很显然,在搜索单词的第二次出现的时候,必须首先知道此单词。后向引用允许正则表达式模式参照前面的匹配内容(在这个例子中,就是第一次匹配的单词)。 理解这个特性的最好方式就是看看它的使用。下面的文本中包含了三组需要定位的重复单词: 文本 This is a block of of text, several words here are are repeated, and and they should not be. 正则表达式 [ ]+(/w+)[ ]+/1 结果 This is a block of of text, several words here are are repeated, and and they should not be. 分析 此模式可以工作,但是为什么可以工作呢?“[ ]+ ”匹配一个或者更多空格,“/w+”匹配一个或者更多的文字数字式字符,而“[ ]+”则用来匹配尾部的空格。但是注意到这里的“ /w+ ”加上了括号使其成为子表达式。此子表达式并不是用于重复匹配,而且本例中也不需要重复。这里的子表达式仅仅是对表达式进行分组,标记此子表达式供以后使用。模式的最后部分是“ /1 ”,这是对子表达式的后向引用,所以当“ /w+ ”匹配了单词 of ,“ /1 ”也将匹配 of ,当“ /w+ ”匹配了单词 and ,“ /1 ”也将匹配 and 。 注意:术语后向应用是因为这些实体将引用以前的子表达式。 但是“ /1 ”的实际含义是什么呢?它匹配模式中第一个子表达式。同理,“ /2 ”将匹配第二个子表达式,“ /3 ”将匹配第四个,依此类推。“[ ]+(/w+)[ ]+/1”因此将可以匹配所有重复出现的单词。 提示:你可以将后向应用理解成变量。 现在你已经看到了后向引用的用法,再来看看前面的 HTML 例子。使用后向引用,可以创建一个模式用来匹配开始标签和结束标签(忽略所有不匹配的标签对)。下面是这个例子: 文本

Welcome to my Homepage

Content is divided into two sections:

ColdFusion

Information about Macromedia ColdFusion.

Wireless

Information about Bluetooth, 802.11, and more.

This is not valid HTML

正则表达式 <[hH]([1-6])>.*?

结果

Welcome to my Homepage

Content is divided into two sections:

ColdFusion

Information about Macromedia ColdFusion.

Wireless

Information about Bluetooth, 802.11, and more.

This is not valid HTML

分析 同样的,在这里找到了三个匹配:一个

对和两个

对。就像以前一样,“<[hH]([1-6])>”将匹配任何的段落标签。但是和以前不一样的是,这里的“ [1-6] ”使用了小括号括起来成为了子表达式。这样,匹配结束标签的模式可以通过“ ”中的“ /1 ”来引用此子表达式。“ (1-6) ”是一个可以匹配数字 1 到 6 的子表达式,“ /1 ”因此可以匹配相同的数字。在这种情况下,“

This is not valid HTML

”将不能匹配。 笔记:非常遗憾的是,后向引用语法在不同的正则表达式实现中是不一样的。 JavaScript 中使用 / 来表示后向引用(除了 $ 使用时的替换操作),Macromedia ColdFusion 和vi也是这样。 Perl 语言使用的是 $ (所以 $1 表示这里的 /1 )。 .NET 正则表达式支持返回一个包含匹配名为 Groups 属性的对象,所以 C# 中的match.Groups[1]将引用第一个匹配,Visual Basic .NET中的match.Groups(1)将引用第一个匹配。 PHP 通过名为 $matches 的数组返回此信息,所以 $matches[1] 引用第一个匹配(尽管可以通过标志来改变)。在 JAVA 和 Python 语言中则返回包含一个数组名为 group 的匹配对象。 具体的正则表达式实现相关信息可以参看附录 1 :流行应用和语言中的正则表达式。 注意:后向引用只能够引用子表达式(需要使用小括号括起来)。

提示 :引用的匹配一般是从 1 开始。在大多数的实现中,匹配 0 可以用来引用整个表达式。

笔记:正如你所看到的,子表达式是通过相对位置来引用的: /1 引用第一个, /5 引用第五个,等等。尽管获得了广泛的支持,这个语法有着一个严重的问题:移动或者修改子表达式(也因此改变了子表达式的顺序)将会破坏模式,增加或者删除子表达式将会带来更大的问题。为了能够克服这个缺点,现在有些新的正则表达式实现支持命名引用,也就是说为每个可能引用的子表达式给定一个唯一的名称,在以后可以通过此名称来引用(而不是相对位置)。命名引用在本书中并没有包含,因为这还不是一个广泛支持的特性,而且支持此特性的正则表达式实现的语法都很不一样。尽管如此,如果你使用的应用或者语言支持命名引用的话(如 .NET ),最好是利用这种特性的好处。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值