正则表达式教程之前后查找lookaround详解

本文实例讲述了正则表达式教程之前后查找lookaround。分享给大家供大家参考,具体如下:

注:在所有例子中正则表达式匹配结果包含在源文本中的【和】之间,有的例子会使用Java来实现,如果是java本身正则表达式的用法,会在相应的地方说明。所有java例子都在JDK1.6.0_13下测试通过。

一、问题引入

在HTML页面中,匹配出一对标签之间的文本,如匹配出页面的标签,即<title>与</title>之间的文本:

文本:<head><TITLE>welcome to my page</title></head>

正则表达式:<[Tt][Ii][Tt][Ll][Ee]>.*?</ [Tt][Ii][Tt][Ll][Ee]>

结果:<head>【<TITLE>welcome to my page</title>】</head>

分析:<[Tt][Ii][Tt][Ll][Ee]>表示不区分大小写,这个模式匹配到了title标签以及它们之间的文本,但是并不完美,因为我们只想要title标签之间的文本,而不包括标签本身。解决这个问题我们就需要用到前后查找(lookaround)。

二、向前查找

向前查找指定了一个必须匹配但不在结果中返回的模式。向前查找实际上就是一个子表达式,它以?=开头,需要匹配的文本跟在=的后面。

看一个匹配出一个URL地址中协议部分的例子:

文本:http://blog.csdn.net/mhmyqn

正则表达式:.+(?=:)

结果:【http】://blog.csdn.net/mhmyqn

分析:URL地址中协议部分是在:之前的部分,模式.+匹配任意文本,子表达式(?=:)匹配:,但是被匹配到的:并没有出现在结果中。我们使用?=向正则表达式引擎表明,只要找到:就行了,但不包括在最终的返回结果里。这里如果不使用向前匹配(?=:),而是直接使用(:),那么匹配结果就会是http:了,它包括了:,并不是我们想要的。

注意:前后查找中的前、后是指模式与被查找文本的相对位置而言的,左为前,右为后。即向前查找为:xxx(?=xxx),而向后查找为(?<=xxx)xxx,向后查找在接下来会介绍到。

三、向后查找

向后查找操作符是?<=。但是并不是所有的正则表达式实现都支持向后查找,JavaScript就不支持,java语言支持向后查找。

比如要查找文本当中的价格(以$开头,后面跟数字),结果不包含货币符号:

文本:category1:$136.25,category2:$28,category3:$88.60

正则表达式:(?<=\$)\d+(\.\d+)?

结果:category1:$【136.25】,category2:$【28】,category3:$【88.60】

分析:(?<=\$)模式匹配$,\d+(\.\d+)?模式匹配整数或小数。从结果可以看出,结果不没有包括货币符号,只匹配出了价格。如果不使用向后查找,情况会是什么样呢?使用模式$\d+(\.\d+)?,这样会把$包含在结果中。使用模式\d+(\.\d+)?,又会把categery1(23)中的数字也匹配出来,都不是我们想要的。

注意:向前查找模式的长度是可变的,它们可以包含.、*、+之类的元字符;而向后查找模式只能是固定长度,不能包含.、*、+之类的元字符。

四、把向前查找和向后查找结合起来

把向前查找和向后查找结合起来使用,即可解决前面HTML标签之间的文本的问题:

文本:<head><TITLE>welcome to my page</title></head>

正则表达式:(?<=<[Tt][Ii][Tt][Ll][Ee]>).*?(?=</ [Tt][Ii][Tt][Ll][Ee]>)

结果:<head><TITLE>【welcome to my page】</title></head>

分析:从结果可以看出,问题完美的解决了。(?<=<[Tt][Ii][Tt][Ll][Ee]>)是一个向后操作,它匹配<title>但不消费它,(?=</[Tt][Ii][Tt][Ll][Ee]>)是一个向前操作,它匹配</title>但不消费它。最终返回的匹配结果只包含了标签之间的文本了。

五、对前后查找取非

前面说到的向前查找和向后查找通常都是用来匹配文本,其目的是为了确定将被返回的匹配结果的文本的位置(通过指定匹配结果的前后必须是哪些文本)。这种用法叫正向前查找和正向后查找。还有一种负向前查找和负向后查找,是查找那些不与给定模式相匹配的文本。

前后查找的操作符:

(?=) 正向前查找
(?!) 负向前查找
(?<=) 正向后查找
(?<!) 负向后查找

比如一段文本中即有价格(以$开头,后面跟数字)和数量,我们要找出价格和数量,先来看查找价格:

文本:I paid $30 for 10 apples, 15 oranges, and 10 pears. I saved $5 onthis order.

正则表达式:(?<=\$)\d+

结果:I paid 【$30】 for 10 apples, 15 oranges, and 10 pears. I saved 【$5】 on thisorder.

查找数量:

文本:I paid $30 for 10 apples, 15 oranges, and 10 pears. I saved $5 onthis order.

正则表达式:\b(?<!\$)\d+\b

结果:I paid $30 for 【10】 apples, 【15】 oranges, and 【10】pears. I saved $5 on this order.

分析:(?<!\$)表示一个负向后查找,它使得结果只包含那些不以$开头的数值。

六、小结

有了前后查找,就可以对最终的匹配结果包含哪些内容做出精确的控制。前后查找操作使我们可以利用子表达式来指定文本匹配操作发生的位置,并收到只匹配不消费的效果。

PS:这里再为大家提供2款非常方便的正则表达式工具供大家参考使用:

JavaScript正则表达式在线测试工具:
http://tools.jb51.net/regex/javascript

正则表达式在线生成工具:
http://tools.jb51.net/regex/create_reg

希望本文所述对大家正则表达式学习有所帮助。

(0)

相关推荐

  • JAVA中正则表达式匹配,替换,查找,切割的方法

    正则表达式的查找;主要是用到String类中的split(); String str; str.split();方法中传入按照什么规则截取,返回一个String数组 常见的截取规则: str.split("\\.")按照.来截取 str.split(" ")按照空格截取 str.split("cc+")按照c字符来截取,2个c或以上 str.split((1)\\.+)按照字符串中含有2个字符或以上的地方截取(1)表示分组为1 截取的例子; 按照

  • js正则查找match()与替换replace()用法实例

    本文实例讲述了js中正则的查找match()与替换replace()的用法.分享给大家供大家参考.具体如下: 复制代码 代码如下: <html> <head> <script type="text/javascript"> //string.match(正则):正则查找字符串,返回符合正则的字符或字符串 function t1(){  var con = document.getElementsByName('content')[0].value;/

  • 正则表达式匹配,替换,查找

    上篇文章给大家介绍了Java正则表达式匹配,替换,查找,切割的方法,接下来,通过本篇文章给大家介绍js 正则匹配.查找与替换,具体内容请看下文. js 正则匹配.查找与替换 RegExp对象RegExp对象表示正则表达式,它是对字符串执行模式匹配的强大工具.直接量语法/pattern/attributes创建RegExp对象的语法:newRegExp(pattern,attributes);参数参数patter... RegExp 对象 RegExp 对象表示正则表达式,它是对字符串执行模式匹配

  • 学习Java正则表达式(匹配、替换、查找)

    本文为大家分享了Java正则表达式的匹配.替换.查找和切割操作,有兴趣的朋友可以参考一下 import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; public class test { public static void main(String[] args) { getStrings(); //用正则表达式获取指定字符串内容中的指定内容 System.out.pri

  • 如何在PHP中使用正则表达式进行查找替换

    1. preg_match - 执行一个正则表达式匹配int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )搜索subject与pattern给定的正则表达式的一个匹配. pattern:要搜索的模式,字符串类型.subject :输入字符串. matches:如果提供了参数matches,它将被填充为搜索结果. $matche

  • 正则表达式教程之操作符及说明详解

    本文实例讲述了正则表达式中的操作符及说明.分享给大家供大家参考,具体如下: 一.普通字符 包括所有未显式指定为元字符的打印和非打印字符组成,如大小写字母.数字.标点符号等. 二.元字符 元字符是一些在正则表达式里有着特殊含义的字符.因为元字符在正则表达式里有着特殊的含义,所以这些字符不能用来代表它们本身,必须通过给它加个反斜杠前缀来转义,如此得到的转义序列将匹配那个字符本身而不是它特殊的元字符含义.如[表示一个字符集合的开始,如果在正则表达式中要匹配[,那么需要这样引用:\[,才能表示[本身.

  • 正则表达式教程之位置匹配详解

    本文实例讲述了正则表达式教程之位置匹配.分享给大家供大家参考,具体如下: 注:在所有例子中正则表达式匹配结果包含在源文本中的[和]之间,有的例子会使用Java来实现,如果是java本身正则表达式的用法,会在相应的地方说明.所有java例子都在JDK1.6.0_13下测试通过. 一.问题引入 如果想匹配一段文本中的某个单词(暂不考虑多行模式,将在后面介绍),我们可能会像下面这样: 文本:Yesterday is history, tomorrow is a mystery, but today i

  • 正则表达式教程之子表达式用法分析

    本文实例讲述了正则表达式教程之子表达式用法.分享给大家供大家参考,具体如下: 注:在所有例子中正则表达式匹配结果包含在源文本中的[和]之间,有的例子会使用java来实现,如果是java本身正则表达式的用法,会在相应的地方说明.所有java例子都在JDK1.6.0_13下测试通过. 一.问题引入 首先来看一个例子,有的短语如Windows 2000虽然是多个单词组成,但其实是一个整体,HTML页面中可以使用非换行空格( 即non-breaking space)让它在浏览器中显示在一行上,现在来匹配

  • 正则表达式教程之重复匹配详解

    本文实例讲述了正则表达式教程之重复匹配.分享给大家供大家参考,具体如下: 注:在所有例子中正则表达式匹配结果包含在源文本中的[和]之间,有的例子会使用Java来实现,如果是java本身正则表达式的用法,会在相应的地方说明.所有java例子都在JDK1.6.0_13下测试通过. 一.有多少个匹配 前面几篇讲的都是匹配一个字符,但是一个字符或字符集合要匹配多次,应该怎么做呢?比如要匹配一个电子邮件地址,用之前说到的方法,可能有人会写出像\w@\w\.\w这样的正则表达式,但这个只能匹配到像a@b.c

  • Powershell学习笔记--使用正则表达式查找文件

    支持所有PS版本 Get-ChildItem 不支持文件高级筛选.它只能使用简单的通配符,但不能使用正则表达式. 围绕这个问题,我们可以使用-match命令来筛选. 下面这个例子将获得所有windows目录下包含至少连续有两个数字的文件同时文件名长度不超过8个字符: Get-ChildItem -Path $env:windir -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.BaseName -match '\d{2}' -

  • 正则表达式验证IPV4地址功能实例分析

    本文实例讲述了正则表达式验证IPV4地址功能.分享给大家供大家参考,具体如下: IPV4地址由4个组数字组成,每组数字之间以.分隔,每组数字的取值范围是0-255. IPV4必须满足以下四条规则: 1.任何一个1位或2位数字,即0-99: 2.任何一个以1开头的3位数字,即100-199: 3.任何一个以2开头.第2位数字是0-4之间的3位数字,即200-249: 4.任何一个以25开头,第3位数字在0-5之间的3位数字,即250-255. 这样把规则全部罗列出来之后,构造一个正则表达式的思路就

  • 正则表达式查找相似单词的方法

    本文通过展示各种不同的正则表达式结构,以及在实际应用中会用到的技巧,熟悉掌握正则表达式的应用. 问题描述: 在这个实例中你要解决如下几个问题. 1.想要在一个字符串中找到所有的color和colour. 2.想要找到这3个以"at"结尾的单词中的任意一个:bat.cat或rat. 3.想要找到以phobia结尾的单词. 4.想要找的名字"Steven"的常见变形:Steve.Steven和Stephen. 5.想要匹配术语"regular expressi

  • 用正则查找html中有id属性的html标签

    如: 字符串<div style="float:left" id="ab">123213</div><div class="a123">21314423</div> 不匹配<div class="a123">--</div>的内容 写这个例子可以用 <[a-zA-Z0-9][^>]+?id=[^>]+?>.*?</div>

随机推荐