时间:2021-05-02
本文实例讲述了正则表达式教程之前后查找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.
分析:(?<!\$)表示一个负向后查找,它使得结果只包含那些不以$开头的数值。
六、小结
有了前后查找,就可以对最终的匹配结果包含哪些内容做出精确的控制。前后查找操作使我们可以利用子表达式来指定文本匹配操作发生的位置,并收到只匹配不消费的效果。
希望本文所述对大家正则表达式学习有所帮助。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
命令中的正则表达式如果要在命令输出或文本中筛选内容时使用模糊查找,就需要使用正则表达式。正则表达式是一套由多个元字符组成的模糊查找模式,使用正则表达式可以快速查
本教程旨在帮助你驾驭Java正则表达式,同时也帮助我复习正则表达式。什么是正则表达式?正则表达式定义了字符串的模式。正则表达式可以用来搜索、编辑或处理文本。正则
上篇文章给大家分享了php正则表达式安全教程之基础篇,本文将继续延伸有关php正则表达式的知识,具体内容请看下文。php正则表达式的各种操作符的运算优先级相同优
以前我要查找数据都是使用like后来发现mysql中也有正则表达式了并且感觉性能要好于like,下面我来给大家分享一下mysqlREGEXP正则表达式使用详解,
本文实例讲述了正则表达式教程之子表达式用法。分享给大家供大家参考,具体如下:注:在所有例子中正则表达式匹配结果包含在源文本中的【和】之间,有的例子会使用java