玩转python爬虫之正则表达式
面对大量杂乱的代码夹杂文字我们怎样把它提取出来整理呢?下面就开始介绍一个十分强大的工具,正则表达式! 1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。 正则表达式是用来匹配字符串非常强大的工具,在其他编程语言中同样有正则表达式的概念,Python同样不例外,利用了正则表达式,我们想要从返回的页面内容提取出我们想要的内容就易如反掌了。 正则表达式的大致匹配过程是:
2.正则表达式的语法规则 下面是Python中正则表达式的一些匹配规则,图片资料来自CSDN 3.正则表达式相关注解 (1)数量词的贪婪模式与非贪婪模式 注:我们一般使用非贪婪模式来提取。 (2)反斜杠问题 Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r””表示。同样,匹配一个数字的”d”可以写成r”d”。有了原生字符串,妈妈也不用担心是不是漏写了反斜杠,写出来的表达式也更直观勒。 4.Python Re模块 Python 自带了re模块,它提供了对正则表达式的支持。主要用到的方法列举如下 #返回pattern对象 re.compile(string[,flag]) #以下为匹配所用函数 re.match(pattern,string[,flags]) re.search(pattern,flags]) re.split(pattern,maxsplit]) re.findall(pattern,flags]) re.finditer(pattern,flags]) re.sub(pattern,repl,count]) re.subn(pattern,count]) 在介绍这几个方法之前,我们先来介绍一下pattern的概念,pattern可以理解为一个匹配模式,那么我们怎么获得这个匹配模式呢?很简单,我们需要利用re.compile方法就可以。例如 pattern = re.compile(r'hello') 在参数中我们传入了原生字符串对象,通过compile方法编译生成一个pattern对象,然后我们利用这个对象来进行进一步的匹配。 另外大家可能注意到了另一个参数 flags,在这里解释一下这个参数的含义: 参数flag是匹配模式,取值可以使用按位或运算符'|'表示同时生效,比如re.I | re.M。 可选值有: • re.I(全拼:IGNORECASE): 忽略大小写(括号内是完整写法,下同) 在刚才所说的另外几个方法例如 re.match 里我们就需要用到这个pattern了,下面我们一一介绍。 注:以下七个方法中的flags同样是代表匹配模式的意思,如果在pattern生成时已经指明了flags,那么在下面的方法中就不需要传入这个参数了。 # -*- coding: utf-8 -*- #导入re模块 import re # 将正则表达式编译成Pattern对象,注意hello前面的r的意思是“原生字符串” pattern = re.compile(r'hello') # 使用re.match匹配文本,获得匹配结果,无法匹配时将返回None result1 = re.match(pattern,'hello') result2 = re.match(pattern,'helloo CQC!') result3 = re.match(pattern,'helo CQC!') result4 = re.match(pattern,'hello CQC!') #如果1匹配成功 if result1: # 使用Match获得分组信息 print result1.group() else: print '1匹配失败!' #如果2匹配成功 if result2: # 使用Match获得分组信息 print result2.group() else: print '2匹配失败!' #如果3匹配成功 if result3: # 使用Match获得分组信息 print result3.group() else: print '3匹配失败!' #如果4匹配成功 if result4: # 使用Match获得分组信息 print result4.group() else: print '4匹配失败!' 运行结果 hello hello 3匹配失败! hello 匹配分析 1.第一个匹配,pattern正则表达式为'hello',我们匹配的目标字符串string也为hello,从头至尾完全匹配,匹配成功。 2.第二个匹配,string为helloo CQC,从string头开始匹配pattern完全可以匹配,pattern匹配结束,同时匹配终止,后面的o CQC不再匹配,返回匹配成功的信息。 3.第三个匹配,string为helo CQC,从string头开始匹配pattern,发现到 ‘o' 时无法完成匹配,匹配终止,返回None 4.第四个匹配,同第二个匹配原理,即使遇到了空格符也不会受影响。 我们还看到最后打印出了result.group(),这个是什么意思呢?下面我们说一下关于match对象的的属性和方法 属性: # -*- coding: utf-8 -*- #一个简单的match实例 import re # 匹配如下内容:单词+空格+单词+任意字符 m = re.match(r'(w+) (w+)(?P<sign>.*)','hello world!') print "m.string:",m.string print "m.re:",m.re print "m.pos:",m.pos print "m.endpos:",m.endpos print "m.lastindex:",m.lastindex print "m.lastgroup:",m.lastgroup print "m.group():",m.group() print "m.group(1,2):",m.group(1,2) print "m.groups():",m.groups() print "m.groupdict():",m.groupdict() print "m.start(2):",m.start(2) print "m.end(2):",m.end(2) print "m.span(2):",m.span(2) print r"m.expand(r'g gg'):",m.expand(r'2 13') ### output ### # m.string: hello world! # m.re: # m.pos: 0 # m.endpos: 12 # m.lastindex: 3 # m.lastgroup: sign # m.group(1,2): ('hello','world') # m.groups(): ('hello','world','!') # m.groupdict(): {'sign': '!'} # m.start(2): 6 # m.end(2): 11 # m.span(2): (6,11) # m.expand(r'2 13'): world hello! (2)re.search(pattern,flags]) #导入re模块 import re # 将正则表达式编译成Pattern对象 pattern = re.compile(r'world') # 使用search()查找匹配的子串,不存在能匹配的子串时将返回None # 这个例子中使用match()无法成功匹配 match = re.search(pattern,'hello world!') if match: # 使用Match获得分组信息 print match.group() ### 输出 ### # world (3)re.split(pattern,maxsplit]) import re pattern = re.compile(r'd+') print re.split(pattern,'one1two2three3four4') ### 输出 ### # ['one','two','three','four',''] (4)re.findall(pattern,flags]) import re pattern = re.compile(r'd+') print re.findall(pattern,'one1two2three3four4') ### 输出 ### # ['1','2','3','4'] (5)re.finditer(pattern,flags]) import re pattern = re.compile(r'd+') for m in re.finditer(pattern,'one1two2three3four4'): print m.group(),### 输出 ### # 1 2 3 4 (6)re.sub(pattern,count]) import re pattern = re.compile(r'(w+) (w+)') s = 'i say,hello world!' print re.sub(pattern,r'2 1',s) def func(m): return m.group(1).title() + ' ' + m.group(2).title() print re.sub(pattern,func,s) ### output ### # say i,world hello! # I Say,Hello World! (7)re.subn(pattern,count]) import re pattern = re.compile(r'(w+) (w+)') s = 'i say,hello world!' print re.subn(pattern,s) def func(m): return m.group(1).title() + ' ' + m.group(2).title() print re.subn(pattern,s) ### output ### # ('say i,world hello!',2) # ('I Say,Hello World!',2) 5.Python Re模块的另一种使用方式 在上面我们介绍了7个工具方法,例如match,search等等,不过调用方式都是 re.match,re.search的方式,其实还有另外一种调用方式,可以通过pattern.match,pattern.search调用,这样调用便不用将pattern作为第一个参数传入了,大家想怎样调用皆可。 函数API列表 match(string[,pos[,endpos]]) | re.match(pattern,flags]) search(string[,endpos]]) | re.search(pattern,flags]) split(string[,maxsplit]) | re.split(pattern,maxsplit]) findall(string[,endpos]]) | re.findall(pattern,flags]) finditer(string[,endpos]]) | re.finditer(pattern,flags]) sub(repl,count]) | re.sub(pattern,count]) subn(repl,count]) |re.sub(pattern,count]) 具体的调用方法不必详说了,原理都类似,只是参数的变化不同。小伙伴们尝试一下吧~ 小伙伴们加油,即使这一节看得云里雾里的也没关系,接下来我们会通过一些实战例子来帮助大家熟练掌握正则表达式的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |