标签:
在爬虫的学习过程中,又一个你必须要掌握的知识点就是正则表达式
爬虫程序需要爬取你需要的东西,那么就对爬取的结果进行筛选,正则表达式就起到这样的作用
如果你学过任何一门语言,相信你都会接触正则表达式。并且正则表达式大多相同。
不管怎样,就像开头说的那样,因为这是爬虫基础教程。所以这篇文章要详细的说一下python的
正则表达式。开始进入正题吧。
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
首先第一步,看正则表达式模式
模式字符串使用特殊的语法来表示一个正则表达式:
字母和数字表示他们自身,一个正则表达式模式中的字母和数字匹配同样的字符串。下面说一些模式
1.1
^ --匹配字符串的开头,在多行模式中匹配每一行的开头
实例:
import re value = "hello python" value_last = re.match(r‘^hello‘,value) print(value_last)
输出的结果是:
<_sre.SRE_Match object; span=(0, 5), match=‘hello‘>
如果换成这样呢:
import re value = "hello python" value_last = re.match(r‘^python‘,value) print(value_last)
输出的结果是:
None
1.2
$ --匹配字符串的末尾,在多行模式中匹配每一行的结尾
这个和1.1的用法相同这里不再举例
1.3
. --匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
怎么用?看实例:
import re value = "hello python" value_last = re.match(r‘^.ello‘,value) print(value_last)
输出的结果是:
<_sre.SRE_Match object; span=(0, 5), match=‘hello‘>
你也可以这样:
import re value = "hello python" value_last = re.match(r‘^.ello.......‘,value) print(value_last)
输出的结果是:
<_sre.SRE_Match object; span=(0, 12), match=‘hello python‘>
好调皮的说。
1.4
\ --转义字符,使后一个字符改变原来的意思
什么意思呢?比如1.3的"."本来表示匹配任意一个字符,但是如果加上"\"则表示匹配的就是小数点"."
如果仍然听不懂那么看例子:
首先尝试在1.3的例子上把.前面加上\
import re value = "hello python" value_last = re.match(r‘^\.ello‘,value) print(value_last)
输出的结果是:
None
但是如果是这样,我们修改一下value的值
value = ".hello"
这时候你需要去匹配".",怎么匹配呢?也许你会说用"."但是如果是"*"呢?
value = re.match(r‘^\..ello‘,value)
输出的结果是:
<_sre.SRE_Match object; span=(0, 6), match=‘.hello‘>
我希望你是了解上一个表达式的。
1.5
[...] --字符集,对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围
,如[abc]或者[a-c],如果第一个字符是^表示取反,如[^abc]表示不是abc的其它字符
,所有特殊字符在字符集中都失去其原有含义。表示一组字符,单独列出:[abc]匹配‘a‘,‘b‘,‘c‘。
import re value = "hello" value_last = re.match(r‘^h.[a-z][^abce]‘,value) print(value_last)
输出的结果是:
<_sre.SRE_Match object; span=(0, 4), match=‘hell‘>
1.6
* --匹配前一个字符0或者无限次
就是这个意思:
import re value = "heo" value_last = re.match(r‘hel*o‘,value) print(value_last)
你看,虽然表达式没有l但是我没在意加了l但是不可以删除,俺么我只好用*之前说了可以匹配前一个字符0次
那么我要这样写
value = ‘value_last = re.match(r‘hel*o‘,value)‘
value_last = re.match(r‘hel*o‘,value)
结果你应该也能想到吧,没错:<_sre.SRE_Match object; span=(0, 11), match=‘hellllllllo‘>
1.7
+ --匹配前一个字符1次或者无限次,就是比*大一咯,不用举例了吧
1.8
? --匹配前一个字符0次或者一次,这个也不用多说了
1.9
{m} --匹配前一个字符m次
1.11
{m,n} --匹配前一个字符m到n次以上几个不用多说吧!如果不懂那你就从头学起吧!
1.12
a|b --匹配a或者b
import re value = "hellllllllo" value_last = re.match(r‘h|e‘,value) print(value_last)
输出的结果是:
<_sre.SRE_Match object; span=(0, 1), match=‘h‘>
1.13
(...) --匹配括号内的表达式,也表示一个组
看到1.12的例子,你会不会问,如果在1.12的基础撒谎那个,像匹配he怎么办,当然python会帮你解决这个问题
import re value = "heeho" value_last = re.match(r‘(h|e){2,}‘,value) print(value_last)
输出的结果是:
<_sre.SRE_Match object; span=(0, 4), match=‘heeh‘>
1.14
(?:re) --类似(...)但是不表示一个组
1.15
再继续说特殊构造之前,先要说一下正则表达式的修饰符 - 可选标志
正则表达式可以包含一些可选标志修饰符来控制匹配的模式,修饰符被指定为一个可选标志,多个标志可以通过
按位OR(|)它们来指定,如re.I|re.M,被设置成I,M标志:
re.I--使匹配对大小写不敏感
re.L--使本地化识别(locale-aware)匹配
re.M--多行匹配,影响^和$
re.S--使"."匹配包括换行在内的所有字符
re.U--根据Unicode字符集解析字符,这个标志影响\w,\W,\b,\B
re.X--该标志通过给予你更加灵活的格式以便你将正则表达式写的更易于理解。
1.16
说完了可选标志,让我们继续往下学习
(?imx) --正则表达式包含三种可选标志:i,m,x。只影响括号中的区域
看一个实例:
import re value = "Hello" value_last = re.match(r‘(?i)hello‘,value) print(value_last)
输出的结果是:
<_sre.SRE_Match object; span=(0, 5), match=‘hello‘>
1.17
(?#...) --将后面的内容当作注释忽视掉
1.18
(?=...) --之后的字符串内容需要匹配表达式才能成功匹配。
看具体例子:
import re value = "Hello" value_last = re.match(r‘(?i)h(?=[a-b])‘,value) print(value_last)
这种情况下,由于h后面的"e"不是在a-b范围内,因此之后的字符串内容不匹配表达式,这样
尽管(?i)h匹配H,还是不能匹配。
因此输出的结果是:None
import re value = "Hello" value_last = re.match(r‘(?i)h(?=[a-z])‘,value) print(value_last)
这种情况下,"e"属于a-z,匹配表达式,因此输出的结果是:H
1.19
(?!...) --之后的字符串需要不匹配表达式才能成功
1.20
(?<=...) --之前的字符串需要匹配表达式才能成功
1.21
(?<!...) --之前的字符串需要不匹配表达式才能成功
1.22
看完上面的1.1到1.21相信正则表达式的匹配模式你已经掌握差不多了。再来看一些简单的匹配模式
\d --匹配数字,等价于[0-9]
\D --匹配非数字,等价于[^\d]
\s --匹配空白字符,等价于[\t\r\n\f\v]
\S --匹配非空白字符,等价于[^\s]
\w --匹配单词字符,等价于[A-Za-z0-9]
\W --匹配非单词字符,等价于[^\w]
\A --匹配字符串开始
\Z --匹配字符串结束,如果存在换行,只匹配到换行前的结束字符串
\z --匹配字符串结束
\G --匹配最后匹配完成的位置
\b --匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b‘ 可以匹配"never" 中的 ‘er‘,但不能匹配 "verb" 中的 ‘er‘。
\B --匹配非单词边界。‘er\B‘ 能匹配 "verb" 中的 ‘er‘,但不能匹配 "never" 中的 ‘er‘。
\n, \t, --匹配一个换行符。匹配一个制表符。等
\1...\9 --匹配第n个分组的子表达式。
好了,说完了python中的匹配模式,下面该介绍python正则表达式中常用的函数了
1.1
首先第一个函数就是刚刚在实例中一直用到的
re.match() --尝试从字符串的开始匹配一个模式
语法:re.match(pattern,string,flags=0)
pattern是要匹配的正则表达式,string是要匹配的字符串,flags标志位,用于控制正则表达式的匹配方式
如果匹配成功的话返回一个匹配的对象,否则返回None
可以用group(num)或者groups()匹配对象函数来获取匹配表达式
group(num = 0)匹配整个表达式的字符串,group()可以一次输入多个组号,这种轻情况下,它将返回一个包含哪些组所对应值的元组
groups()返回一个包含所有小组字符串的元组,从1到所含的小组号
import re value = "hello world,2015!" value_last = re.match(r‘(^[a-z]*)\s(\w*),(\d*.)‘,value) if value_last: print(value_last.group()) print(value_last.group(1)) print(value_last.group(2)) print(value_last.group(3))
输出的结果是:
hello world,2015!
hello
world
2015!
1.2
re.search() --会在字符串内查找模式匹配,直到找到第一个匹配
re.search(pattern.string,flags = 0)
与match相同。
两者的区别在于:
re.match只匹配字符串的开始,如果字符串开始不负责正则表达式,则匹配失败,函数返回None,
但是re.search()匹配整个字符串,直到找到一个匹配
import re value = "hello world,2015!" value_last = re.match(r‘2015‘,value) if value_last: print(‘match-->‘,value_last.group()) else: print("No match!") value_end = re.search(r‘2015‘,value) print(‘search-->‘,value_end.group())
输出的结果是:
No match!
search--> 2015
1.3
sub(pattern,repl,string,max=0)
替换字符串的匹配项
import re phone = "2015-5-31 # This is my Num" num = re.sub(r‘#.*$‘,"",phone) print("Phone Num:",num) num = re.sub(r‘\D‘,"",phone) print("Phone Num:",num)
输出的结果是:
Phone Num: 2015-5-31
Phone Num: 2015531
1.4
split(pattern,string[,maxsplit])
按照能够匹配的字串将string分割后返回列表,maxsplit指定最大分割次数
import re value = "1.one2.two3.three" value_last = re.split(r‘\d.‘,value) print(value_last)
输出的结果是:
[‘‘, ‘one‘, ‘two‘, ‘three‘]
1.5
findall(pattern.string[,flags])
搜索string,以列表形式返回全部能匹配的子串
import re value = "1.one2.two3.three" value_last = re.findall(r‘\d.‘,value) print(value_last)
返回的结果是:
[‘1.‘, ‘2.‘, ‘3.‘]
1.6
finditer(pattern,string[,flags])
返回一个能顺序访问的迭代器
import re value = "1.one2.two3.three" value_last = re.finditer(r‘\d.‘,value) for x in value_last: print(x.group())
返回的结果是:
1.
2.
3.
如果你对迭代器不了解的话请翻阅我之前的博客。
正则表达式的就到这边,正则表达式需要自己经常联系,有了这三篇的基础
set(),deque,正则表达式,下一篇我们就能详细的介绍怎么去写爬虫程序了。
钟志远 江苏南京 904727147
标签:
原文地址:http://my.oschina.net/u/2391943/blog/486779