正则表达式,Regular Expression,是平时编程中经常用到的一种技术,用于匹配字符串。在爬虫、自然语言处理、文本分析里面经常会用到。严格来说,它可以看作是一种特殊的“编程语言”了,搞懂它,无论是java,python,php,都能轻松的应用。
关于正则表达式,教程有一大堆,也算是一项基本技能吧,想要熟练的掌握,那就得多写,说到底也是一种工具罢了。下面这些教程和文章都讲的比较清楚:
关于正则表达式,我这里不多说,有了正则表达式的基础,我就来整理一下python下正则表达式的用法,主要用例子来说明,争取做到拿来就能用。
在python中,正则表达式模块是re模块,使用直接import re
即可。
1.基本函数
1.1 re.match函数
1.1.1 语法
re.match(pattern, string, flags=0)
1.1.2 参数
参数 | 描述 |
---|---|
pattern | 匹配的正则表达式 |
string | 要匹配的字符串。 |
flags | 标志位,用于控制正则表达式的匹配方式,如下表 |
可以使用多个标志位,用或连起来就可以,比如re.I | re.M
,貌似也是这两个标志位比较常用。
标志位 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
1.2 re.search函数
1.2.1 语法
re.search(pattern, string, flags=0)
1.2.2 参数
同re.match
1.3 re.findall函数
返回匹配的所有结果,是一个list
1.4 处理返回对象
1.4.1 用法
使用re.match或者re.search方法,如果没有匹配,返回None,如果匹配到了,则返回一个对象,可以通过以下方法对对象进行操作。
1.5 match和search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
2. python例子
2.1 抓取网页中所有超链接
用这个正则表达式可以匹配超链接:<a.*?href=.*?<\/a>
(注释:这里,.
是另一个元字符,匹配除了换行符以外的任意字符。*
同样是元字符,不过它代表的不是字符,也不是位置,而是数量——它指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配。因此,.*
连在一起就意味着任意数量的不包含换行的字符。)
代码如下:
import re import urllib url = "http://www.lookfor404.com" result = urllib.urlopen(url).read() reg = re.compile("<a.*?href=.*?<\/a>") #编译正则表达式 #findall方法 urls = reg.findall(s) #找到所有超链接 #和以下句子等价 #urls = re.findall(reg,s) print len(urls) #打印超链接数量,urls是一个list
2.2 匹配网页标题
以我的博客为例,匹配网页标题,正则表达式我设置为:<title>.*?</title>
,代码如下:
import re import urllib url = "http://www.lookfor404.com" result = urllib.urlopen(url).read().decode('utf-8') reg = re.compile("<title>.*?</title>") #编译正则表达式 #search方法 title = re.search(reg,result) #找到标题,匹配到第一个就行 #和以下句子等价 #title = reg.search(result) print title.group(0) #打印匹配的内容
最后输出的结果是:
<title>找不到的博客 – 李鹏飞在这里写字</title>
2.3 找到特定的内容
仍然是2.2的例子,这次我不要html标签,只要标题,代码如下,其实只是正则表达式里面加了个括号:<title>(.*?)</title>
:
import re import urllib url = "http://www.lookfor404.com" result = urllib.urlopen(url).read().decode('utf-8') reg = re.compile("<title>(.*?)</title>") #编译正则表达式 #search方法 title = re.search(reg,result) #找到标题,匹配到第一个就行 #和以下句子等价 #title = reg.search(result) print title.group(0) #打印匹配的内容 print print title.group(1) #打印匹配的内容,去除html
输出两行结果:
<title>找不到的博客 – 李鹏飞在这里写字</title>
找不到的博客 – 李鹏飞在这里写字
而在2.2中,如果执行print print title.group(1)
则会出错。
2.4 匹配菜单内容
抓取网页里面的所有目录,查看网页源代码,我用这样的正则表达式来匹配:<li id=”menu-item-.*?<a href=.*?>(.*?)</a></li>
,其中的(.*?)
就是我要提取的文字。代码如下:
import re import urllib url = "http://www.lookfor404.com" result = urllib.urlopen(url).read().decode('utf-8') reg = re.compile(' <li id="menu-item-.*?<a href=.*?>(.*?)</a></li> ') #编译正则表达式 #findall方法 menu = re.findall(reg,result) #找到标题,匹配到第一个就行 #和以下句子等价 #menu = reg.findall(result) #打印menu for item in menu: print item
最后输出如下:
似乎输出的不完整,哦,因为有多级菜单,li标签里面还有li标签,这里只抓取了嵌套在最里面的菜单,仅作为用法例子,就不深究了。
以上例子属于比较常用的例子,并没有涉及到一些复杂的用法,之后碰到更多再继续更新上来。