正则表达式:正则表达式的模块是re,它的基本语法规则就是指定一个字符序列。

导入正则表达式:

import re

正则表达式常用字符集:

  .:

#表示任意匹配

import re

s = 'pyc py pyo'
res = r'py.'
print(re.findall(res,s))

输出结果:
['pyc', 'py ', 'pyo']

 []:

(1)指定一个字符集:[abc];[a-z]

>>> s = 'tip top tap tep'
>>> res = r't[io]p'
>>> re.findall(res,s)
['tip', 'top']

(2)元字符在[]中不起作用:[akm$] 

(3)补齐匹配不在区间范围的字符:[^5] #取反,即:取出不是数字5的字符

^:

#它出现在非[]中含义是匹配行首;若^出现中[]中,则表示取反

>>> r = r'^abc'   #以abc开头字符串
>>> re.findall(r,'aaabc')
[]
>>> re.findall(r,'abc3')
['abc']
>>> re.findall(r,'^abc3')
[]

$:

#它出现在非[]中含义是匹配行尾

>>> s = '123abc456eabc789'
>>> re.findall(r'789$',s)
['789']

\:

#转义符

>>> r = r'\^abc'    #转义后面的^为一个普通字符,并非匹配行首的意思
>>> re.findall(r,'^abc3')
['^abc']
>>> re.findall(r,'abc3')
[]
\d  #匹配数字[0-9]
\D  #匹配非数字[^0-9]
\s  #匹配空白字符,如回车,空格等[\t\n\f\v]
\S  #匹配非空字符 [^\t\n\f\v]
\w  #匹配数字和字母 [0-9a-zA-Z]
\W  #匹配非数字和字母 [^0-9a-zA-Z]

例:

>>> r = r'010-\d{8}'   #\d{8}表示数字重复8次
>>> re.findall(r,'010-123456789')
['010-12345678']
>>> re.findall(r,'010-1234567')
[]

|:

#任意匹配一个,它总是尝试匹配左边的表达式,一旦匹配成功则跳过匹配右边的表达式,如果|没有在括号()中,则它的范围是整个表达式。

abc|def 匹配的字符串为:abc 或者 def

*:

#将*前面的字符重复0次或多次

>>> r = r'ab*'
>>> re.findall(r,'a')  #重复b零次
['a']
>>> re.findall(r,'ab')  #重复b一次
['ab']
>>> re.findall(r,'abb')   #重复b两次
['abb']
>>> re.findall(r,'abbbbbb')   #重复多次b
['abbbbbb']

+:

#将+前面的字符重复1次或多次(即:至少重复一次)

>>> r = r'ab+'
>>> re.findall(r,'a')
[]
>>> re.findall(r,'ab')
['ab']
>>> re.findall(r,'abbb')
['abbb']

?:

#将?前面的字符重复0次或1次,用于表示可选项,即可有可无的字符

>>> r = r'010-?\d{8}$'
>>> re.findall(r,'010-12345678')
['010-12345678']
>>> re.findall(r,'01012345678')
['01012345678']

(.+?):

#提取单个位置的字符串

例1:提取字符串'a123b'中的'123'

import re
str = 'a123b'
r = r'a(.+?)b'
res = re.findall(r,str)
print(res)

输出结果:

['123']

例2:提取字符串'a123bc456d'中,从a到d之间数字部分

import re
str = 'a123b456d'
r = 'a(\d+)b(\d+)d'
res = re.findall(r,str)
print(res)

输出结果

[('123', '456')]

例3:匹配多行

import re
str = 'a123\nb456\nd789'
r = r'a(\d+).b(\d+).d(\d+)'
res = re.findall(r,str,re.S)  #加上re.S让.匹配包括换行符在内的所有字符
print(res)

输出结果:

[('123', '456', '789')]

{m}:

#m为数字  #重复{}前面字符m次

{m,n}  m,n为数字  #表示最小重复m次,最多重复n次
>>> r = r'a{1,3}'
>>> re.findall(r,'a')
['a']
>>> re.findall(r,'aa')
['aa']
>>> re.findall(r,'aaa')
['aaa']
>>> re.findall(r,'aaaa')
['aaa', 'a']

(?:):

#无捕获组:将一部分规则最为一个整体对它进行操作
(?#):

#注释:写入注释

特殊字符类:

. :  #匹配除 "\n" 之外的任何单个字符,如果要匹配\n,使用[.\n]

\d:  #匹配一个数字字符[0-9]

\D:  #匹配非数字集合[^0-9]

\s:  #匹配任何空白字符,包括空格,制表符,换页符等[\f\n\r\t\v]

\S:  #匹配非空白字符[^\f\n\r\t\v]

\w:  #匹配字母数字下划线任何单字符[A-Za-z0-9_]

\W:  #匹配任何非单词字符[^A-Za-z0-9_]

编译正则表达式:可以实现匹配速度提高

>>> import re
>>> p = re.compile('ab*')   #编译正则表达式
>>> p.findall('abbbb')    #调用
['abbbb']

执行匹配:

(1)match():#匹配元素在该字符串中开始的位置,如果匹配则返回一个对象,否则返回为空。

>>> r = re.compile(r'cctv',re.I)
>>> r.match('cctv hello')     #匹配对象在起始位置
<_sre.SRE_Match object at 0x00000000032B15E0>
>>> r.match('hello cctv')   #匹配对象不在起始位置
>>>    #返回空

(2)search() : #扫描整个字符串,并返回第一个匹配的项。

>>> cctv_re = re.compile(r'cctv',re.I)  
>>> cctv_re.search('hello cctv')
<_sre.SRE_Match object at 0x00000000033305E0>
>>> cctv_re.search('cctv hello')
<_sre.SRE_Match object at 0x0000000003330648>
>>> cctv_re.search('hello cctv hello')
<_sre.SRE_Match object at 0x00000000033305E0>   #只要匹配re规则,就会返回第一个匹配的对象,无论元素位置在哪。

(3)findall():  #返回字符串中所有匹配re的项。

模块级函数:

(1)sub()  #替换

>>> r = r'c..v'
>>> re.sub(r,'python','ccav cctv ccsv cccc')  #r表示前面定义的正则表达式,'python'为替换后的字符串,'ccav cctv...'表示原字符串。
'python python python cccc'   #匹配正则表达式的内容都会被替换 

(2)subn()  #替换多次

>>> s = 'ccav cctv ccsv ssrv svvv'
>>> r = r's..v'
>>> re.subn(r,'aaa',s,1)
('ccav cctv ccsv aaa svvv', 1)  #只有第一个匹配到的项被替换成'aaa',虽然后svvv也符合re,但匹配次数设置的为是1,所以不替换。

(3)split()  #切割

>>> ip = '192.168.1.1'
>>> re.split(r'\.',ip)
['192', '168', '1', '1']   #以.分割字符串

编译标志:

(1)re.S  #使.匹配包括行在内的所有字符,包括换行等字符

>>> import re
>>> r = r'cctv.net'
>>> re.findall(r,'cctv%net')
['cctv%net']
>>> re.findall(r,'cctvanet')
['cctvanet']
>>> re.findall(r,'cctv\nnet')
[]
>>> re.findall(r,'cctv\nnet',re.S)
['cctv\nnet']

(2)re.I   #使匹配对大小写不敏感

>>> cctv_re = re.compile(r'cctv',re.I)   #忽略大小写
>>> cctv_re.findall('CCTV')
['CCTV']
>>> cctv_re.findall('cctv')
['cctv']
>>> cctv_re.findall('ccTV')
['ccTV']

(3)re.L   #使本地化识别匹配日、法语等

(4)re.M   #多行匹配,影响^和$。当一个字符串有很多行时,匹配时就需要用M参数

>>> s = r'''
hello cctv
cctv hello
hello cctv hello
cctv hi
'''
>>> r = r'^cctv'
>>> re.findall(r,s)
[]
>>> s
'\nhello cctv\ncctv hello\nhello cctv hello\ncctv hi\n'
>>> re.findall(r,s,re.M)
['cctv', 'cctv']

(5)re.X   #该标志通过给予你更灵活的格式,以便你将正则表达式写得更易于理解

>>> tel = r'''
\d{3,4}
-?
\d{8}
'''
>>> re.findall(tel,'010-12345678')
[]
>>> tel
'\n\\d{3,4}\n-?\n\\d{8}\n'
>>> re.findall(tel,'010-12345678',re.X)
['010-12345678']

分组:只提取分组部分内容

例1:匹配邮箱地址,结尾是.com或.cn

>>> email = r'\w+@\w+(\.com|\.cn)'
>>> re.match(email,'aaa@bbbb.com')
<_sre.SRE_Match object at 0x0000000003237558>
>>> re.match(email,'aaa@bbbb.cn')
<_sre.SRE_Match object at 0x00000000032375D0>
>>> re.match(email,'aaa@bbbb.net')
>>> 
>>> re.findall(email,'aaa@bbbb.com')
['.com']   #分组原因,返回分组的内容

例2:如果想提取s字符串中以cctv开头,后面的值

>>>s = '''
hello cctv
cctv hello  
hello cctv hello
cctv hi

'''

>>> r = r'cctv (.+)'
>>> re.findall(r,s)
['hello', 'hello', 'hi']

 

例3:小爬虫:下载贴吧或空间中所有图片

#!/usr/bin/python
import re
import urllib
def getHTML(url):   #下载整个链接的url
        page = urllib.urlopen(url)
        html = page.read()
        return html
def getImg(html):   #过滤,只下载.jpg的图片
        reg = r'src="(.*?\.jpg)" width'
        imgre = re.compile(reg)  #做编译,为了运行的更快
        imglist = re.findall(imgre,html)
        x = 0
        for imgurl in imglist:
                urllib.urlretrieve(imgurl,'%s.jpg' % x)
          x += 1 html
= getHTML('http://tieba.baidu.com/p/4760488708') getImg(html)

 

正则表达式常用方式:

整数(包括正整数和负整数): ^-?\d+$
正整数: ^[0-9]*[1-9][0-9]*$
负整数:^-[0-9]*[1-9][0-9]*$
非正整数(负整数和零):^((-\d+)|0+))$
非负整数(正整数和零):^(\d)|(0+)$

正浮点数:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^((-((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
非负浮点数:^\d+(\.\d+)?$
非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$
英文字符串: ^[a-zA-Z]+$
英文大写字符串: ^[A-Z]+$
英文小写字符串: ^[a-z]+$
英文加数字字符串: ^[a-zA-Z0-9]+$
英文数字加下划线: ^\w+$
E-mail地址: ^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
URL: ^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$ 或: ^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$
邮政编码: ^[1-9]\d{5}$
中文: ^[\u0391-\uFFE5]+$
电话号码: ^((\d2,3)|(\d{3}\-))?(0\d2,3|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$
手机号码: ^((\d2,3)|(\d{3}\-))?13\d{9}$
匹配首尾空格: (^\s*)|(\s*$)
匹配HTML标记: <(.*)>.*<\/\1>|<(.*) \/>
匹配空行: \n[\s| ]*\r
提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
提取信息中的图片链接:(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
提取信息中的IP地址:(\d+)\.(\d+)\.(\d+)\.(\d+)
提取信息中的中国手机号码:(86)*0*13\d{9}
提取信息中的中国固定电话号码:(\d3,4|\d{3,4}-|\s)?\d{8}
提取信息中的中国电话号码(包括移动和固定电话):(\d3,4|\d{3,4}-|\s)?\d{7,14}
提取信息中的中国邮政编码:[1-9]{1}(\d+){5}
提取信息中的浮点数(即小数):(-?\d*)\.?\d+
提取信息中的任何数字 :(-?\d*)(\.\d+)?
IP:r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
电话区号:/^0\d{2,3}$/
腾讯QQ号:^[1-9]*[1-9][0-9]*$
帐号(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

 

posted on 2016-09-01 17:36  PingY  阅读(474)  评论(0编辑  收藏  举报