1、正则表达式:是一种小型的、高度专业化的编程语言,在Python中内嵌在Python中,并通过 re 模块实现;;使用时要导入import re
可以为想要匹配的相应字符串集指定规则
该字符串集可能包含英文语句、Email地址、命令等
使用RE以各种方式修改或分割字符串
2、字符匹配
普通字符:大多 数字、字母、字符 一般都会和自身匹配;如正则表达式test会和字符串‘test’完全匹配
元字符: . ^ * + ? {} [] \ | ()
3、[]
常用来指定一个字符集:[abc] [a-z]
元字符在字符集中不起作用 [akm$]
补集匹配不在区间范围内的字符 [^5]
Eg:
>>> import re
>>> s = r'abc'>>> s='abc'>>> re.findall(s,'aaa') re模块中 findall(正则规则,字符串) 方法能够以列表的形式放回能匹配的字符串[]>>> re.findall(s,'abcaaaaaaa')['abc']>>> re.findall(s,'abcaaaaaaabcaaaa')['abc', 'abc']>>>>>>>>> st = 'top tip twp twp tep'>>> res = r'top' 定义的正则规则>>> re.findall(res,st) st中是否含有top字符['top']>>>>>> res = r't[io]p' 包含tip或top字符>>> re.findall(res,st)['top', 'tip']>>>>>> res = r't[^io]p' 只要不包含tip和top字符;^在字符集中[],表示非;在‘ ’中表示匹配首行匹配>>> re.findall(res,st)['twp', 'twp', 'tep']
4、^
匹配首行。除非设置multline标志,它只是匹配字符串的开始。在MULTILINE模式里,它也可以直接匹配字符串的每个换行
Eg:
>>> s='hello world, hello girl'
>>> r = r'hello'>>> re.findall(r,s)['hello', 'hello']>>> r = r'^hello' 首行必须是hello字符>>> re.findall(r,s)['hello']>>>>>> s='world, hello girl'>>> r = r'^hello'>>> re.findall(r,s)[]
5、$
匹配行尾。行尾被定义要么是字符串尾,要么是一个换行字符后面的任何位置
Eg1:
>>> s='hello world, hello girl'
>>> r = r'girl$'>>> re.findall(r,s)['girl']>>> s='world, hello girl boy'>>> r = r'girl$'>>> re.findall(r,s)[]
E:2:
r = r‘x[0123456]x’ 表示x0x、x1x、x2x、x3x、x4x、、、
可简写成:r = r'x[0-6]x'
r = r'x[a-zA-Z0-9]x' 中间是a-z、A-Z、0-9之间
Eg3:
6、\
反斜杠后面可以加不同的字符以表示不同特殊意义。。也可以用于取消所有的元字符:\[ 或 \\
\d 匹配任何十进制数,相当于类[0-9]
\D 匹配任何非数字字符,相当于类[^0-9]
\s 匹配任何空白字符,相当于[\t\n\r\f\v]
\S 匹配任何非空白字符,相当于类[^\t\n\r\f\v]
\w 匹配任何字母数字字符,相当于类[a-zA-Z0-9]
\W 匹配任何非字母数字字符,相当于类[^a-zA-Z0-9]
Eg:
>>> r = r'\^abc' 取消了^元字符的含义;若不加\,后面打印不出^abc
>>> re.findall(r,'^abc')['^abc']r = r'[0-9]' = r'\d'
7、重复:正则表达式第一功能是能够匹配不定长的字符集,另一个功能就是可以指定正则表达式的一部分的重复次数{}
Eg:
北京固定电话号码: 010-12345678
>>> r = r'^010-[0-9]'>>> re.findall(r,'010-123')['010-1']>>> re.findall(r,'010-x')[]>>> r = r'^010-\d\d\d\d\d\d\d\d'>>> re.findall(r,'010-87654321')['010-87654321']>>> re.findall(r,'010-8765')[]>>>>>> r = r'^010-\d{8}'>>> re.findall(r,'010-8765') 不是八位数不打印出来[]>>> re.findall(r,'010-87650000\') 不是数字的话报错 File "<stdin>", line 1 re.findall(r,'010-87650000\') ^SyntaxError: EOL while scanning string literal>>> re.findall(r,'010-87650000')['010-87650000']
8、* :指定前一个字符可以被匹配零次或更多次,而不是只有一次。匹配引擎会试着重复尽可能多的次数(不超过整数界定范围,20亿)
a[bcd]*b -- 'abcbd'
Eg:
>>> r = r'ab*'
>>> re.findall(r,'a')['a']>>> re.findall(r,'abbbbbbb')['abbbbbbb']9、 + :表示匹配一或更多次。。。+与*不同之处:*匹配0或更多次,+匹配1或更多次
Eg:
>>> r = r'ab+'
>>> re.findall(r,'a')[]>>> re.findall(r,'ab')['ab']>>> re.findall(r,'abbbbbbb')['abbbbbbb']>>>
10、? :匹配1次或0次,可以认为它用于标识某事物是可选的;;加在+后,最小匹配ab
Eg:r = r'010-a{8}$' 号码中 - 可有可无都可以输入的时候
>>> r = r'010-?\d{8}$'
>>> re.findall(r,'010-12345678')['010-12345678']>>> re.findall(r,'01012348888')['01012348888']>>> re.findall(r,'010--12348888')[]
11、 {m,n}
其中m和n是十进制整数,该限定符的意思是至少有m个重复,至多到n个重复
忽略m会认为下边界是0,而忽略n的结果将是上边界为无穷大
{0,}等同于*,{1,}等同于+,而{0,1}则与?相同;;如果可以的话最好使用*、+、?
Eg:
>>> r = r'a{ 1,3}'
>>> re.findall(r,'a')['a']>>> re.findall(r,'aa')['aa']>>> re.findall(r,'aaaa')['aaa', 'a']
12、使用正则表达式:re模块提供了一个正则表达式引擎的接口,可以让你将REstring编译成对象并用他们来进行匹配。若常用的正则,应先编译再使用,这样速度快很多
Eg:
>>> r1 = r'\d{3,4}-?\d{8}'
>>> re.findall(r1,'010-123456789')['010-12345678']>>> re.findall(r1,'010-123456789766555')['010-12345678']>>> re.findall(r1,'010-123455')[]>>> p_tel = re.compile(r1) 将正则表达式的字符串形式编译成对象p_tel,然后直接使用p_tel进行匹配>>> p_tel<_sre.SRE_Pattern object at 0x01D16700>>>> p_tel.findall('010-12345678')['010-12345678']>>> p_tel.findall('010-1234567800000')['010-12345678']>>> p_tel.findall('010-12345')[]Eg:匹配不区分大小写
>>> cstv_re = re.compile(r'cstv',re.I) re.I是属性,不区分字母大小写
>>> cstv_re.findall('CSTV')['CSTV']>>> cstv_re.findall('cstv')['cstv']>>> cstv_re.findall('cStV')['cStV']
13、反斜杠 :字符串钱加‘r’ 反斜杠就不会被任何特殊方式处理
14、执行匹配 :RegexObject实例有一些方法和属性,完整的列表可查阅Python library reference
match() 决定RE是否在字符串刚开始的位置匹配 一般用来判断有值还是没有值
search() 扫描字符串,找到这个RE匹配的位置
findall() 找到RE匹配的所有字符串,并把他们作为一个列表返回
finditer() 找到RE匹配的所有字符串,并把他们作为一个迭代器返回
以上常用的方法中,如果没有匹配到的话,match()和search()将返回None;如果成功的话,就会返回一个MatchObject实例
Eg:
>>> cstv_re = re.compile(r'cstv',re.I)
>>> cstv_re.match('cstv hello')<_sre.SRE_Match object at 0x01CBEA30> 有相应的数据,会返回一个对象;没有的话就会返回空>>> cstv_re.match('hello cstv') cstv不在首位置,所以返回None>>>>>> cstv_re.search('cstv hello') search要匹配的字符串无论在任何位置,只要有就可以正常匹配<_sre.SRE_Match object at 0x01CBED40>>>> cstv_re.search('hello cstv')<_sre.SRE_Match object at 0x01CBEA30>>>> cstv_re.search('hello cstv hello world')<_sre.SRE_Match object at 0x01CBED40>
15、MatchObject实例方法
group() 返回被RE匹配的字符串
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配(开始,结束)的位置
>>> x = cstv_re.match('cstv hello boy girl cstv')
>>> x<_sre.SRE_Match object at 0x01CBEA30>>>> x.group()'cstv'实际程序中,最常见的做法是将MatchObject保存在一个变量中,然后检查是否为None
Eg:
import re 引用re模块 p = re.compile(r'abc') 创建一个pattern实例,用的是compile函数。‘abc’就是正则表达式的字符串 m = p.match('abc string goes here') 用match方法返回一个match对象;match方法中的参数也就是要匹配的字符串 if m: print 'Match found:',m.group() 打印所有匹配的成员 else: print 'no match'
16、模块级函数:re模块也提供了顶级函数调用如match()、search()、sub()、subn()、split()、findall()等
Eg:
>>> s = 'hello cstv'>>> s.replace('cstc','python')'hello cstv'>>> s.replace('csvt','python')'hello cstv'>>> s.replace('cstv','python') replace()函数替换时,必须字符全部一致时才会替换'hello python'>>>>>> rs = r'c..t'>>> re.sub(rs,'python','csvt caat cvvt cccc cjkj') sub()函数实现只要满足开头是c结尾是t的字符都满足即可;必须为三个参数sub(正则,要替换的字符,要查找的字符串)'python python python cccc cjkj'>>> re.subn(rs,'python','csvt caat cvvt cccc cjkj') 一共替换了多少次('python python python cccc cjkj', 3)>>>>>> ip = '192.168.1.66'
>>> ip.split('.') 字符串中的split['192', '168', '1', '66']>>> s = '123+345-789*000'>>> re.split(r'[\+\-\*]',s) 不可以写成 re.split(r'[+-*]',s),因为+(匹配一次或更多次)、-()、*都有各自的含义['123', '345', '789', '000']
17、编译标志--flags
标志 含义
DOTALL,S 使 . 匹配包括换行在内的所有字符
IGNORECASE,I 使匹配对大小写不敏感
LOCALE,L 做本地化识别(local-aware)匹配
MULTILINE,M 多行匹配,影响^和$
VERBOSE,X 能够使用REs的verbose状态,使之被组织得更清晰易懂
Eg:
>>> r1 = r'cstv.net'
>>> re.findall(r1,'cstv.net')['cstv.net']>>> re.findall(r1,'cstvonet')['cstvonet']>>> re.findall(r1,'cstvxnet')['cstvxnet']>>> re.findall(r1,'cstv\net')[]>>> re.findall(r1,'cstv\nnet')[]>>> re.findall(r1,'cstv\nnet',re.S)['cstv\nnet']Eg:
Eg:匹配不区分大小写
>>> cstv_re = re.compile(r'cstv',re.I) re.I是属性,不区分字母大小写
>>> cstv_re.findall('CSTV')['CSTV']>>> cstv_re.findall('cstv')['cstv']>>> cstv_re.findall('cStV')['cStV']Eg:
>>> s = """
... hello cstv... cstv hello... hello cstv hello... cstv hhhh... """>>> r = r'^cstv'>>> re.findall(r,s) 当对多行字符串操作时,实际上有\n[]>>> s'\nhello cstv\ncstv hello\nhello cstv hello\ncstv hhhh\n'>>> re.findall(r,s,re.M)['cstv', 'cstv']Eg:
>>> 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']
18、分组 “(” 和 “)”
Eg:
找出s中形式为 hello scr=... yes 的形式
>>>r1 = r'hello src=.+ yes'
>>>re.findall(r1,s)
['hello src=cstv yes','hello src=python yes']
>>>r1 = r'hello src=(.+) yes' 优先取出分组的内容
>>>re.findall(r1,s)
['cstv','python']
Eg:
>>> email = r'\w{3}@\w+(\.com|\.cn)' com结尾或cn结尾
>>> re.match(email,'zzz@cstv.com')<_sre.SRE_Match object at 0x0256A1E0>>>> re.match(email,'zzz@cstv.cn')<_sre.SRE_Match object at 0x02586BA0>>>> re.match(email,'zzz@cstv.org')>>> re.match(email,'zzz@cstv.cn')<_sre.SRE_Match object at 0x0256A1E0>>>> re.findall(email,'zzz@cstv.cn')['.cn']
re.finditer(pattern, string[, flags]) 返回string中所有与pattern相匹配的全部字串,返回形式为迭代器
19、获取网页上的图片,小爬虫
# !/user/bin/env python # -*- coding: utf-8 -*- import re,urllib def getHtml(url): page = urllib.urlopen(url) html = page.read() return html def getImage(html): reg = r'src="(.*?\.jpg)" size' imagre = re.compile(reg) imglilst = re.findall(imagre,html) x = 0 for imgurl in imglilst: urllib.urlretrieve(imgurl,'%s.jpg' % x) x+=1 html = getHtml('http://tieba.baidu.com/p/4575159738') print getImage(html)