9.1 初识正则表达式
正则表达式:
是一种小型的、高度专业化的编程语言
其内嵌在python中,通过“re”模块实现
它是一门独立的编程语言,可以和任意其它语言结合使用
功能:
1、匹配不定长的字符集
2、指定正则表达式的一部分的重复次数
普通字符匹配:
大多数字母和字符一般都会和自身匹配。 #如:正则表达式test和字符串”test”完全匹配
元字符匹配:
. ^ $ * + ? {} [] \ | () #此处共11个
9.2 正则表达式匹配
正则表达式匹配语句:
变量1=原始数据
变量2=r"匹配规则"
re.findall(匹配规则(变量2),原始数据(变量1))
无元字符:常规匹配
字母和字符的自身匹配。
# -*- coding:utf-8 -*-
import re
s="top tip tup typ ttp trp tep twp tqp" #这是原始字符串
res=r"tip" #想要匹配的字符串
print re.findall(res,s) #匹配语句。re.findall(匹配规则,原始数据)
元字符:.
占位。其位置可以是任意一个字符
# -*- coding:utf-8 -*-
import re
s="cast coit cnnt cert cdetcswt" #最后没有空格
res=r"c..t" #中间可以是任意字符
print re.findall(res,s) #都会被匹配到
元字符:[]
常用来指定一个字符集。
元字符在字符集中不起作用。注意[ ]至少一边要无数据
补集匹配不在区间范围内的字符。注意[ ]两边都要有数据
# -*- coding:utf-8 -*-
import re
s="top tip tup typ ttp trp tep twp tqp"
res=r"t[uio]p" #中间字母是u\i\o的被匹配
res=r"t[^uio]p" #中间字母不是u\i\o的被匹配(取反)
res=r"t[a-zA-Z0-9]p" #中间字母是a-z、A-Z、0-9的都匹配
print re.findall(res,s)
---------------------------------------------------------------------------------
#元字符当作普通符号处理
# -*- coding:utf-8 -*-
import re
res=r"t[^asdfg]" #注意!前提是[]至少一边无数据!若两边都有数据则元字符生效
res=r"t[\^asdfg]p" #转义字符。此时[]两边都可有数据
print re.findall(res,"t^pkm") #此处原始数据不是变量,而是直接写了
元字符:^
匹配行首。字符串的开始
# -*- coding:utf-8 -*-
import re
s="top tip tup typ ttp trp tep twp tqp"
res=r"^top" #匹配原始数据行首。若开头是则返回,否则返回空。不匹配中间数据
print re.findall(res,s)
元字符:$
匹配行尾。行尾:字符串尾或者换行字符后面的任何位置
# -*- coding:utf-8 -*-
import re
s="top tip tup typ ttp trp tep twp tqp"
res=r"top$" #匹配原始数据末尾。若末尾是则返回,否则返回空。不匹配中间数据
print re.findall(res,s)
元字符:\
1、用于转义元字符,使其普通化。
2、后面加不同字符可以表示不同特殊意义。如下:
\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_] #注意那个下划线!
# -*- coding:utf-8 -*-
import re
res=r"\d" #等价于:res="[0-9]"
print re.findall(res,"567") #匹配567
res=r"t[\^asdfg]" #转义字符。
print re.findall(res,"t^") #转义后元字符当作普通符号处理
元字符:*
指定一个字符串可以被匹配0次或多次
# -*- coding:utf-8 -*-
import re
res=r"ab*" #将*前面的一个字符。即b重复0次以上
print re.findall(res,"a") #将b重复0次。返回a
print re.findall(res,"abbbbbbbb") #将b重复了多次
元字符:+
指定一个字符串可以被匹配1次或多次
# -*- coding:utf-8 -*-
import re
res=r"ab+" #将+前面的一个字符。即b重复1次以上
print re.findall(res,"a") #将b重复0次。返回空
print re.findall(res,"abbbbbbbb") #将b重复了多次
元字符:?
指定一个字符串可以被匹配1次或0次
# -*- coding:utf-8 -*-
import re
#以电话号为例:010-12345678
res=r"^010-?\d{8}" #将?前面的一个字符。即-可有可无
print re.findall(res,"010-36251478") #“-”只能输入0次或1次
res=r"ab+?" #只匹配第一个ab
print re.findall(res,"abbbbabbb") #返回两个ab。其余不返回
元字符:{m,n}
m、n是十进制整数。至少有m个重复,至多有n个重复
忽略m会认为下边界为0。忽略n会认为上边界是无穷大
{0,}等同于*。{1,}等同于+。{0,1}等同于?
# -*- coding:utf-8 -*-
import re
res=r"a{8}" #将{}前面的一个字符。即a重复8次
print re.findall(res,"mbaaaaaaaaaa") #只返回符合规则的。即8个a
res=r"a{4,8}" #至少重复4次,至多重复8次
print re.findall(res,"mbakaaaa") #只返回符合规则的。即4-8个a
元字符:()
分组。
# -*- coding:utf-8 -*-
import re
em1=r"hello src=.+ yes"
em2=r"hello src=(.+) yes" #括号中的字符不会影响到外面
#此处是一堆乱码
Q="""
shudh shi hello src=baidu yes sdi
dhhdih src=google yes idsj
ihsad asihd src=234 yes asi
asij hello src=Alibaba yes asi
"""
print re.findall(em1,Q) #乱码中符合规则的都返回。例:hello src=Alibaba yes
print re.findall(em2,Q) #只返回正则括号里面的。例:Alibaba
9.3 正则表达式-常用函数
编译:
如果有一段正则表达式要经常使用,建议对其进行编译。编译后运行速度将大幅度提高
re.compile(匹配规则(变量))
re.compile()也接受可选的标志参数,常用来实现不同的特殊功能
RE模块级函数:
match():决定RE是否在字符串刚开始的位置匹配。若无匹配则返回None
search():扫描字符串,找到这个RE匹配的位置。若无匹配则返回None
#match和search只返回迭代器类型,不返回具体数据。因此它们有以下方法:
group():返回被RE匹配的字符串
start():返回匹配开始的位置
end():返回匹配结束的位置
span():返回一个元组包含匹配(开始,结束)的位置
sub(匹配规则,目标字串,原始字串):将原始字串中符合匹配规则的字串替换为目标字串
subn():用法功能同上,同时最后返回替换了几处
split():切割
findall():找到RE匹配的所有子串,并把它们作为一个列表返回
其它函数:
finditer():找到RE匹配的所有子串,并把他们作为一个迭代器返回
代码实例:
# -*- coding:utf-8 -*-
import re
#编译:compile
res=r"\d{3,4}-?\d{8}" #区号-电话号
print re.findall(res,"0937-12345678") #正则匹配
dianhua=re.compile(res) #正则表达式的编译
print dianhua.findall("0937-12345678") #编译后的匹配
#匹配:match
HS=r"abcde"
HSQ=re.compile(HS) #注意!编译是过程,不能直接输出
a=HSQ.match("abcde HELLabcdeO") #匹配元素在开头则返回对象,不在开头返回None
print a #只返回对象,没有具体值
print a.group() #返回被匹配到的数据。数据不在开头报错
print a.start() #返回开头目标字串的第一个字母位置。例为:0
print a.end() #返回开头目标字串最后字母的位置。例为:5
print a.span() #返回一个元组。其包含开始和结束的位置。例为:(0,5)
#匹配:search
H=r"abcde"
SQ=re.compile(H,re.I) #注意!编译是过程,不能直接输出
print SQ.search("abcde HELLO abcdde") #匹配元素在任意位置即返回对象
#替换:sub、subn
s="cast coit cnnt cert cdetcswt" #最后没有空格
res=r"c..t"
print re.sub(res,'hello',s) #都被替换为hello
print re.subn(res,'hello',s) #同上。最后返回替换了几处
#切割:split
Q="12+34-56*78/90"
F=r"[\+\-\*\/]" #字符都有特殊含义,因此需要转义。注意中括号
print re.split(F,Q) #以特殊字符切割。
#匹配:finditer
h=r"abcde"
sq=re.compile(h,re.I) #注意!编译是过程,不能直接输出
print sq.finditer("abcde HEabcdeLLO abcdde") #返回迭代器
9.4 正则编译标志
编译标志:
S
:使“.”匹配包括换行在内的所有字符
I
:使匹配对大小写不敏感
L
:做本地化识别匹配
M
:多行匹配。影响^和$
X
:能够对多行正则表达式进行匹配
代码实例:
# -*- coding:utf-8 -*-
import re
#编译标志:S
MQ=r"www.baidu.com"
print re.findall(MQ,"www.baidu.com",re.S) #“.”不能被替换为其它字符
print re.findall(MQ,"www\nbaidu\tcom",re.S) #注意是\n和\t
MW=re.compile(MQ,re.S) #也可以先编译,再匹配
print MW.findall("www.baidu.com")
#编译标志:I
daxiaoxie=r"abcde"
print re.findall(daxiaoxie,"ABCDE",re.I) #不区分大小写编译
da=re.compile(daxiaoxie,re.I) #也可以先编译,再匹配
print da.findall("aBCDe") #大小写混合
#编译标志:M #此处是多行字符串
MR='''
hello nihao
i am liming
hello nihao
i am hanmeimei
'''
res=r"^hello" #匹配行首字母为hello
print re.findall(res,MR,re.M) #匹配多行的hello。例共2个
#编译标志:X
#此处是多行正则表达式
tel=r'''
\d{3,4}
-?
\d{8}
'''
ME="0937-12345678"
print re.findall(tel,ME,re.X) #多行正则表达式的匹配