前面我们说到了如何在Python正则表达式z中匹配中文,说到了另一种方法,这就是如何巧妙的使用Python正则表达式匹配模式的问题了
Python匹配模式
re.compile(strPattern[, flag]):
这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。 第二个参数flag是匹配模式,取值可以使用按位或运算符'|'表示同时生效,比如re.I | re.M。另外,你也可以在regex字符串中指定模式,比如re.compile('pattern', re.I | re.M)与re.compile('(?im)pattern')是等价的。
可选值有:
主要非英文语系字符范围 | ||
模式 | 名称 | 说明 |
re.I | re.IGNORECASE | 忽略大小写(括号内是完整写法,下同) |
re.M | MULTILINE | 多行模式,改变'^'和'$'的行为 |
re.S | DOTALL | 点任意匹配模式,改变'.'的行为, 使".“可以匹配任意字符 |
re.L | LOCALE | 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定 |
re.U | UNICODE | 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性 |
re.X | VERBOSE | 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的: |
具体参见如下代码
#!coding:utf-8
import re
import sys
import urllib2
# 测试匹配中文信息
def TestReChinese( ):
reload(sys)
sys.setdefaultencoding( "utf-8" )
# 这段HTML代码是从博客列表页面中摘取出来的单个博客的信息, 我们要从中摘取出
page = r"""<div class="list_item article_item">
<div class="article_title">
<span class="ico ico_type_Original">
</span>
<h1>
<span class="link_title">
<a href="/gatieme/article/details/43235791">
Python正则表达式匹配中文
</a>
</span>
</h1>
</div>
<div class="article_description">
在使用Python的过程中,由于需求原因,我们经常需要在文本或者网页元素中用Python正则表达式匹配中文,但是我们经常所熟知的正则表达式却只能匹配英文,而对于中文编码却望尘莫及,于是我大量Google,几经Baidu,花了两个多个小时测试,终于发现解决的办法。特记录如下 字符串的角度来说,中文不如英文整齐、规范,这是不可避免的现实。本文结合网上资料以及个人经验,以 python 语言为例,...
</div>
<div class="article_manage">
<span class="link_postdate">2015-01-28 19:34
</span>
<span class="link_view" title="阅读次数">
<a href="/gatieme/article/details/43235791" title="阅读次数">阅读</a>(64)
</span>
<span class="link_comments" title="评论次数">
<a href="/gatieme/article/details/43235791#comments" title="评论次数" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(0)
</span>
<span class="link_edit"><a href="http://write.blog.csdn.net/postedit/43235791" title="编辑">编辑</a>
</span>
<span class="link_delete"><a href="javascript:void(0);" οnclick="javascript:deleteArticle(43235791);return false;" title="删除">删除</a>
</spa </div>
<div class="clear">
</div>
</div>"""
req = urllib2.Request("http://blog.csdn.net/gatieme/article/list/1") # 建立页面请求
req.add_header("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)")
try:
cn = urllib2.urlopen(req)
page = cn.read( )
unicodePage = page.decode("utf-8")
cn.close( )
except urllib2.URLError, e:
print 'URLError:', e.code
return
except urllib2.HTTPError, e:
print 'HTTP Error:' + e.reason
return
# 从博客页面中匹配出每个博客的地 址
reHtml = r'<span class="link_title"><a href="(.*?)">\s*(.*?)\s*</a></span>.*?<span class="link_postdate">(.*?)</span>\s*<span class="link_view" title=".*?"><a href="(.*?)" title=".*?">.*?</a>(.*?)</span>\s*<span class="link_comments" title=".*?"><a href="(.*?)#comments" title=".*?" οnclick=".*?">.*?</a>(.*?)</span>'
#####-----------------------------------------------------------
# [示例1]----写法1 匹配失败, 无法匹配中文
# pattern = re.compile(reHtml)
# myItems = re.findall(pattern, unicodePage)
# [示例1]----写法2 匹配失败, 无法匹配中文
# myItems = re.findall(reHtml, unicodePage)
#####-----------------------------------------------------------
#####-----------------------------------------------------------
# [示例2]----写法1, 匹配成功, re.S使用DOTALL模式可以匹配中文
# 写法说明
# Ⅰ将字符串编译成re.S[DOTALL]模式下正则表达式
# Ⅱ在使用正则表达式文本或者HTML代码中匹配博客信息
pattern = re.compile(reHtml, re.S)
myItems = re.findall(pattern, unicodePage)
# [示例2]----写法2, 匹配成功, re.S使用DOTALL模式可以匹配中文
# Ⅰ将字符串编译成re.S[DOTALL]模式下正则表达式
# Ⅱ直接用编译好的正则表达式在文本或者HTML代码中匹配博客信息
# pattern = re.compile(reHtml, re.S)
# myItems = pattern.findall(unicodePage)
# [示例2]----写法3, 匹配成功, re.S使用DOTALL模式可以匹配中文
# Ⅰ
# Ⅱ不编译正则表达式,直接在文本或者HTML代码中匹配博客信息
# myItems = re.findall(reHtml, unicodePage, re.S)
print len(myItems)
# print myItems
for item in myItems:
urlTitle = item[0].replace("\n", "")
urlView = item[3].replace("\n", "")
urlComments = item[5].replace("\n", "")
# 由于匹配时使用了贪婪模式, 为了匹配出现错误,
# 将某一篇的标题与另一篇博客的发表时间, 阅读次数或者评论条数混淆的匹配成一篇博客信息
# 因此在匹配时,重复的匹配了博客的地址信息
# 当且仅当,博客标题附带的地址信息与博客阅读次数以及评论条数附带的地址信息时同一篇博客的地址时,
# 我们才认为匹配成功
if (urlTitle == urlView) and (urlTitle == urlComments):
print "#------------------------------------------------------"
print "地址:", item[0].replace("\n", ""), # 博客地址URL1(标题附带)
print "标题:", item[1].replace("\n", ""), # 博客标题
print "时间:", item[2].replace("\n", ""), # 博客发表时间
print "阅读:", item[4].replace("\n", ""), # 博客阅读次数信息
print "评论:", item[6].replace("\n", "") # 博客评论条数
print "#-----------------------------------------------------"
print
print
if __name__ == "__main__" :
# 测试正则表达式
reload(sys)
sys.setdefaultencoding("utf-8")
TestReChinese( )