最新消息:20190717 VPS服务器:Vultr新加坡,WordPress主题:大前端D8,统一介绍入口:关于

【教程】详解Python正则表达式之: (?<=…) positive lookbehind assertion 后向匹配 /后向断言

Python re crifan 2105浏览 0评论

Python 2.7手册中的官方解释是:

(?<=...)

Matches if the current position in the string is preceded by a match for ... that ends at the current position. This is called a positive lookbehind assertion. (?<=abc)def will find a match in abcdef, since the lookbehind will back up 3 characters and check if the contained pattern matches. The contained pattern must only match strings of some fixed length, meaning that abc or a|b are allowed, but a* and a{3,4} are not. Note that patterns which start with positive lookbehind assertions will never match at the beginning of the string being searched; you will most likely want to use the search() function rather than the match() function:

>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'

This example looks for a word following a hyphen:

>>> m = re.search('(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'

下面就来详细解释一下,此处的(?<=…)的含义:

1.一般的字符串匹配,都是匹配当前(位置开始往后)的字符串是什么。

而此处的(?<=…) 的功能是,判断(当前位置)之前的内容是什么。

从此处的语法,其实也容易理解:

因为其写法是 <=,即小于等于,分解为小于号和等于号:

  • 小于号:表示从当前位置往前看;
  • 等于号:表示判断前面的内容,是否为 …

所以,也才被称作,positive lookbehind assertion,此处我把其翻译为:后向匹配 ,后向断言。

2.为何要有positive lookbehind assertion?

作为查找字符串,匹配字符串的应用中,在一些复杂的情况时,不仅要判断当前内容是什么,还要判断当前位置之前的内容,是否满足一定条件,然后才好做出最终判断的。

如果了解html源码的话,则很容易理解,一个典型的例子是,img里面标签内,有src,图片的源地址,比如:

<img style="text-align:center;margin:0px auto 10px;zoom:1;display:block" border="0" src="http://1821.img.pp.sohu.com.cn/images/blog/2012/4/12/16/19/u173669005_13766a7cbebg214.jpg">

而想要正常查找一个html页面内的代码,通过

"http://[\w\./]+\.jpg"

去匹配后缀为.jpg类型的图片的话,虽然是可以匹配到的,但是存在一个问题。

那就是,本身html代码中,假如在src值内外部,某人只是也写了http开头的.jpg结尾的地址,但只是为了介绍一个普通的url地址,并非作为图片显示的。

比如:

fake html begin

some sohu blog pic url is something like this:
"http://1802.img.pp.sohu.com.cn/images/blog/2012/4/12/16/20/u173669005_13766a912eag214.jpg"
which use img.pp.sohu.com.cn as its image server.

<img style="text-align:center;margin:0px auto 10px;zoom:1;display:block" border="0" src="http://1821.img.pp.sohu.com.cn/images/blog/2012/4/12/16/19/u173669005_13766a7cbebg214.jpg">

fake html end

此时,如果你还是用上述的匹配规则去匹配,就会五匹配,把非图片类的jpg地址,也都匹配出来了。

而此时,为了避免误匹配,则就可以利用到 positive lookbehind assertion了。

详细的演示代码如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【教程】详解Python正则表达式之: (?<=…) positive lookbehind assertion 后向匹配 /后向断言
https://www.crifan.com/detailed_explanation_about_python_regular_express_positive_lookbehind_assertion

Version:    2012-11-14
Author:     Crifan
"""

import re;

#提示:
#相关教程:
#【教程】详解Python正则表达式之: (?=…) lookahead assertion 前向匹配 /前向断言
#https://www.crifan.com/detailed_explanation_about_python_regular_express_lookahead_assertion

reLookbehindTestStr = """
fake html begin

some sohu blog pic url is something like this:
"http://1802.img.pp.sohu.com.cn/images/blog/2012/4/12/16/20/u173669005_13766a912eag214.jpg"
which use img.pp.sohu.com.cn as its image server.

<img style="text-align:center;margin:0px auto 10px;zoom:1;display:block" border="0" src="http://1821.img.pp.sohu.com.cn/images/blog/2012/4/12/16/19/u173669005_13766a7cbebg214.jpg">

fake html end
"""

# 1. (?<=...) - positive lookbehind assertion 后向匹配 /后向断言

# 下列的,通过普通的匹配操作,会误匹配出来前面的那个jpg图片地址
foundAllJpgUrl = re.findall(u'"(http://[\w\./]+\.jpg)"', reLookbehindTestStr);
print "foundAllJpgUrl=",foundAllJpgUrl; #foundAllJpgUrl= ['http://1802.img.pp.sohu.com.cn/images/blog/2012/4/12/16/20/u173669005_13766a912eag214.jpg', 'http://1821.img.pp.sohu.com.cn/images/blog/2012/4/12/16/19/u173669005_13766a7cbebg214.jpg']

# 而加上了 lookbehind assertion后,就可以精确只匹配 图片地址之前必须是 src= 的jpg图片
foundAllJpgUrl_lookbehind = re.findall(u'(?<=src=)"(http://[\w\./]+\.jpg)"', reLookbehindTestStr);
print "foundAllJpgUrl_lookbehind=",foundAllJpgUrl_lookbehind; #foundAllJpgUrl_lookbehind= ['http://1821.img.pp.sohu.com.cn/images/blog/2012/4/12/16/19/u173669005_13766a7cbebg214.jpg']

 

【总结】

对于这个,相对有点复杂的positive lookbehind assertion,正则匹配规则,一般来说,用到的还是很少的。

但是如果的确需要用到,才会发现,还是会很有用的,可以实现精确的匹配。避免那些误匹配的多余的内容。

转载请注明:在路上 » 【教程】详解Python正则表达式之: (?<=…) positive lookbehind assertion 后向匹配 /后向断言

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
62 queries in 0.125 seconds, using 18.85MB memory