标签:
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‘]
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)
标签:
原文地址:http://www.cnblogs.com/zzfighting/p/5734188.html