Python:正则表达式

python

正则表达式:正则表达式的模块是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}$

以上是 Python:正则表达式 的全部内容, 来源链接: utcz.com/z/388089.html

回到顶部