[b]有些时候我们需要用正则表达式标记要匹配的文本的位置(而不仅仅是文本本身)。这就涉
及到了前后查找(lookaround , 对某一位置的前、后内容进行查找)。[/b]
[b]向后查找: 正如前面?= 将向前查找(查找出现在被匹配文本之后的字符,但不消费那个
字符); 向后查找(查找出现在被匹配文本之前的字符,但不消费他) 向后查找操作符是?<=[/b]
[b]对前后查找取非就前面介绍到的向前查找和向后查找通常来匹配文本,其母的是为了确定
将被返回为匹配结果的文本的位置(通过指定匹配结果的前后必须是哪些文本)
[/b]
及到了前后查找(lookaround , 对某一位置的前、后内容进行查找)。[/b]
先来看一个例子: 我们需要找出html中出现在<title>和</title>标签之间的文字。
文本:
<head>
<title> John's HomePage </title>
</head>
正则表达式: <[tT][iI][lL][eE]>.*</[tT][iI][lL][eE]>
匹配到的是:<title> John's HomePage </title> 但是我们要的结果是:
John's HomePage 这个时候就需要前后查找了(只查出<title> 和</title> 之间的结果)
向前查找: 指定了一个必须匹配但不在结果中返回的模式.向前查找实际就是一个子表达式。
从语法上看:一个向前查找模式其实就是一个以?=开头的子表达式,需要匹配的文本跟在=后
面。
注意: 常见的正则表达式实现都支持向前查找,但是很多都不支持向后查找。
Java , .NET , PHP 和 Perl 等支持向后查找。
来看一例子: 在一文本中获取所有URL的协议名称,以作后续处理。
文本: http://www.huawei.com
https://mail.huawei.com
ftp://ftp.huawei.com
使用向前查找正则: .+(?=:) 结果是: https http ftp
如果不适用向前查找而使用: .+(:) 结果为 https: http: ftp: 包含了多余的:
注意: 向前查找(和向后查找)匹配本身的结果不会出现在返回的结果中. 其返回的结果是0
字节的。 所以前后查找有时也被称为零宽度匹配操作。
提示:任何一个子表达式都可以转换为一个向前查找表达式,只需给其加上一个?=前缀即可。
[b]向后查找: 正如前面?= 将向前查找(查找出现在被匹配文本之后的字符,但不消费那个
字符); 向后查找(查找出现在被匹配文本之前的字符,但不消费他) 向后查找操作符是?<=[/b]
例子: 找出$45.54 $87.55 中价格提取但要求结果中不带有$
正则是(?<=\$)\d+\.\d+
前后查找结合, 如最前面提到的一个例子获取<title></title>之间的文本
(?<=<[tT][iI][lL][eE]>).*(?=</[tT][iI][lL][eE]>)
[b]对前后查找取非就前面介绍到的向前查找和向后查找通常来匹配文本,其母的是为了确定
将被返回为匹配结果的文本的位置(通过指定匹配结果的前后必须是哪些文本)
[/b]
(?=) 正向前查找 (?!) 负向前查找
(?<=) 正向后查找 (?<!) 负向后查找
对于此有一需求
I paid $90 for 10 oranges, 12 pears and 8 apples. I saved $5 on
this order.
1. 只查找钱款: (?<=\$)\d+ 结果是:30 5
2. 只查找数量: \b(?<!\$\d+\b 结果是:10 12 8 注意\b是单词边界。