Python正则表达式

整合了《Python3从入门到实战》及大拿老师的Python笔记

一、正则表达式基本用法

为了避免产生误解: 一般用Python原始字符串的定义方式来定义正则表达式:即在表示正则表达式的字符串前添加字母r;r"\br.t\b"

元字符 . 表达可以匹配除换行符\n之外的任何单个字符,因此,由两个普通字符r,t中间夹一个元素.
组成的正则表达式r.t表示匹配一个r接着任意一个非换行字符再接着一个t

print(re.search(r"r.t", "rut"))

再如:元字符 + 表示其左边的模式可以出现1次以上,如x+表示x模式可以出现1次,2次…而元字符 * 表示其左边的模式x出现0次或很多次

print(re.search(r"r.+", "rsadin"))
print(re.search(r"r.*", "rqsadas "))

方括号 [] 这种元字符用于描述一个字符集,匹配时只能匹配其中的一个字符,例如:[abc]表示匹配的字符只能是a,b或c[0123456789]表示只能匹配0到9这10个数字中的一个

[] 中可以用连字符——表达一个起始字符到结束字符范围内的所有字符,正则表达式[0123456789]可以简化为[0-9],类似的[a-z]表示所有小写字符,[a-zA-Z]表示所有大小写字母,[0-9a-zA-Z]表示所有字母和数字字符

print(re.search(r"r[123]b", "r1b"))
print(re.search(r"r[123]b", "r12b"))
print(re.search(r"r[1-3]b", "r1b"))
print(re.search(r"r[1-3]b", "r12b"))
# 正则表达式中的元字符反斜杠\可以和其他字符结合起来表示某种特殊含义
# \d : 表示所有数字字符 (等价于[0-9])
# \D : 表示出了任何数字
# \s : 表示匹配一个空白字符
# \S : 表示除了空白符号
# 空白字符包括空格,换行,回车,制表,换页,纵向制表(等价于[\t\n\r\f\v])
# \w : 单词字符,就是a-z,A-Z,0-9
# \W : 除了上述的单词字符
# ? : 前面出现的内容零次或者一次
# \n : 表示换行符
# \r : 表示回车符
# \t : 表示制表符
# \v : 表示垂直制表符
# \f : 表示换页符
# \x20 : 表示两位16进制数x20对应的ASCII字符
# \\ : 表示匹配反斜杠符自身\u000A:表示unicode编码\u000A对应的字符,实际就是换行符
# \^ : 表示普通字符^
print(re.search(r"[\d]", "123abc\n"))
print(re.search(r"[\D]", "123abc\n"))
print(re.search(r"[\s]", "123abc\n"))
print(re.search(r"[\S]", "123abc\n"))
print(re.search(r"[\w]", "123abc\n"))
print(re.search(r"[\W]", "123abc\n"))
print(re.search(r"mon(day)?", "mon"))
print(re.search(r"mon(day)?", "monday"))
#  {m,n} : 允许前面内容最少出现m次,最多n次,优先匹配n次,即尽可能多的匹配 ,{m,}表示出现m到正无穷次,有限匹配无穷次
print(re.search(r"ab{3,5}", "abbbb"))
# ^ : 匹配字符串的开头
# $ : 匹配字符串的结尾
print(re.search(r"^\d+$", "123"))
# \b : 匹配单词的边界但 ,\b并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置:例如要查找一个单词he:可以使用\bhe\b表示he的前后是分界 ,\B:表示匹配非单词边界
print(re.search(r"\b", "123"))
# () : 对正则表达式进行分组, 从第一个括号开始, 编号逐渐变大
print(re.search(r"(\d+),(\d*)", "1"))
# \A : 仅匹配字符串开头, 即\Aabcd, 则abcd
print(re.search(r"\Aabcd", "abcde"))
# \Z :仅匹配字符串末尾, abcd\Z, abcd
print(re.search(r"\Zabcd", "abcde"))
# | : 左右任意一个
print(re.search(r"a|b",'abc'))
# (?p<name...> : 分组,除原来的编号再指定一个别名
# (?p=name) : 引用分组
print(r"?p<id>123","1234")
# 在[]出现的元字符"^"表示非,如[^abc]表示匹配除abc外的任意一个字符,
print(re.search(r"[^abc]","abcd"))

二、re的使用步骤

# re使用大致步骤:

1.使用compile将表示正则的字符串编译为一个pattern对象

2.通过pattern对象提供一系列方法对文本进行查找匹配,获得匹配结果,一个match对象

3.最后使用match对象提供的属性和方法获得信息,根据需要进行操作


# re常用函数

1.group(): 获得一个或者多个分组匹配的字符串,当要获得整个匹配的字符串时,直接使用group,或者group(0)

2.start(): 获取分组匹配的子串在整个字符串中的起始位置,参数默认为0

3.end(): 获取分组匹配的子串在整个字符串中的结束位置,默认为0

4.span(): 返回的结果计数(start(group),end(group))

#match和search的不同(后面也会介绍)

import re

p = re.compile(r"\d+")  # r表示字符串不转义
m = p.match("one12towthree213", 3, 26)  # 表示在该字符串中进行查找,3是起始位置,26是结束位置

print(m)  # 匹配成功会返回一个match对象

p = re.compile(r"\d+")  # r表示字符串不转义
m = p.search("one12towthree213", 5, 22)  # 注意这里用的是search,同样表示位置,注意二者区别
# match指定的起始位置一定会有需要匹配的东西,否则找不到
print(m)  # 匹配成功会返回一个match对象

# 从头匹配:search函数在一个主串中搜索和模式串匹配的第一个子串,如果成功,返回一个match对象,否则返回None,
# 函数match用于找开头的零个或多个字符构成的子串与正则表达式相匹配,如果成功返回一个match对象,否则返回None
import re
text = "the cat is there,there is a cat"
print(re.match('the', text))
print(re.match('there', text))
print(re.search('the', text))
print(re.search('there', text))

pattern = 'r.t'
p = re.compile(pattern)
print(type(p))
alist = ["he is arat","the food is Rotten"]
for s in alist:
    match = p.search(s)#注意这里用的是search
    if match: print(match.group())
    else:print('未找到匹配模式串"{}"的子串'.format(pattern))

#常用函数的用法

# I 表示忽略掉大小写
p = re.compile(r"([a-z]+) ([a-z])", re.I)

m = p.match("i am really love wangxiaojing")

print(m)
print(m.group(0))
print(m.start(0))
print(m.end(0))  # 0是所有,1表示第一个
print(m.group(1))
print(m.start(1))
print(m.end(1))

# search,findall,finditer的使用

# search(str [,pos[,endpos]]) : 在字符串中查找匹配,pos和endpos表示起始位置
# findall : 查找所有
# finditer : 查找返回一个iter结果

p = re.compile(r"\d+")

m = p.search("one123two456")

print(m.group())

m1 = p.findall("one123two456")

print(m1)

m2 = p.finditer("one123two456")

for i in m2:
    print(i, end='')
    

import re
for match in re.finditer('ab','abbaaabbbbaaaaa'):#这里理解为在什么里面找什么,search,findall都可以这样使用
    s = match.start()#起始位置
    e = match.end()#终止位置
    print(s,e)
    print(match)

三、高级用法

sub替换

p = re.compile(r'(\w+) (\w+)')

s = "hello 123 wang 456 xiaojiong,i love you"

rst = p.sub(r"hello world", s)  # 用前面的东西替换s中符合的字符串

print(rst)
#替换匹配replacedString = re.sub(pattern,replacement_pattern,string,count=0,flags=0)
#第一个参数pattern是模式匹配的正则表达式,第二个参数是要替换的正则表达式,第三个参数是输入的文本,第四个count是替换模式最大出现次数
import re
text = 'Thr dates of today/nextday are 07/21/2018 and 07/22/2018'
r = re.sub('(\d+)/(\d+)/(\d+)',r'\3-\1-\2',text)#可以这样理解,123代表上述是几号位置,而替换后应该怎么放 3 1 2
print(r)
#每个()包围的每个子表达式称为分组,每个分组都自动分配一个编号,左到右为123

匹配中文

# 匹配中文
# 大部分中文内容表示范围是[u4e00-u9fa5],不包括全角标点

title = u'世界 你好,hello moto' # u相当于是进行了转码处理,具体可以百度

p = re.compile(r'[\u4e00-\u9fa5]+')

rst = p.findall(title)  

print(rst)

贪婪与非贪婪匹配

# 贪婪 : 尽可能多的匹配, (*)表示贪婪匹配
# 非贪婪 : 找到符合条件的最小内容即可 , (*?)表示非贪婪
# 正则默认使用贪婪匹配

title = u'<div>name</div><div>age</div>'

p1 = re.compile(r"<div>.*</div>")
p2 = re.compile(r"<div>.*?</div>")

m1 = p1.search(title)
print(m1.group())

m2 = p2.search(title)
print(m2.group())

切分split

# 按匹配切分
# re.split(pattern,string,maxsplit=0,flags=0)//第一个参数是作分割作用的分割符,第二个是字符串,第三个是最多发生maxsplit个切分
# 并且字符串其余部分将作为列表最后一个元素返回
import re
s = "aa.bb;cc,dd"
print(re.split('[.,;]',s))

圆括号的使用(分组)

#正则表达式中可以用圆括号()标记一个子表达式的开始和结束位置,一个子表达式也称为一个分组(group),正则表达式(123|456){2}表示匹配两次子表达式(123|456)


match1 = re.match(r'(123|456){4}','123123456123')
print(match1)

match2 = re.search(r'(123|456){4}','123123123456213')
print(match2)

match2 = re.findall(r'(123|456){1}','123123123456213')
print(match2)


#正则表达式中用()定义的每个分组都会自动分配一个编号,从左到右出现的分组的编号依次为1...2...3
#正则表达式中可以用反斜杠和分组编号来引用前面定义的分组
#例如: <([a-z]+)<V\1>的第一个分组是([a-z]+),表示至少有一个以上的a到z的字母构成的字符串,这个分组自动有一个编号1,转义字符V表示字符/,最后的表引用的是这个1号分组,因此这个可以用来匹配html和xml的首尾标签,比如:<span></span>或<div></div>等

import re
str1 = 'xue.pro-8@gmail.com,please mail to us '
match = re.search(r'([\w.-]+)@([\w.-]+)', str1)
print(match)
print(match.group(1))
print(match.group(2))

四、扩展符号

# 分组里的?作为扩展符号,它的意义取决于它右边的字符:
# (?PAB) : 匹配字符串AB,可以通过组名访问它
# (?:A) : 匹配由A表示的表达式,,不能通过组名访问它
# (?aiLmsux) : a,i,L,m,s,u和x都是标志
# a :只匹配ASCII字符
# i :忽略大小写
# L :依赖语言环境
# m : 多行
# s : 匹配所有字符
# u : 匹配unicode
# x : 允许正则表达式可以是多行,忽略空白字符,并可以加入注释
# (?#...) : 表示是一个注释,内容仅供阅读,而不是匹配
# A(?=B) : 前瞻断言,仅当表达式A后跟B时才匹配表达式A
# A(?!B) : 否定前瞻断言,仅当表达式A后没有跟B时,它才匹配表达式A
# (?<=B)A : 肯定回顾断言:仅当B紧靠其左侧,才匹配表达式A,它只能匹配固定长度的表达式
# (?<!B)A : 否定回顾断言:仅当B不在其左侧时,才匹配表达式A,它只能匹配固定长度的表达式
# (?P=name) : 匹配已经被匹配过的名为name的分组表达式
import re
m = re.search('(?<=abc)def', 'abcdef')
print(m)
m = re.search('(?<=abc)def', 'abdef')
print(m)

五、一点补充

#match()和search()如果查找失败,则返回一个None对象,如果查找成功,则返回一个match对象,并且当这个对象用于条件表达式时,其值可自动转换为Ture,因此可以用if语句判断查找是否成功
#match的group()方法返回匹配的一个或多个子组,格式为:match.group([group1,group2,...]),如果只有一个参数(子组号或子组名),则返回该参数(子组号或子组名)对应的子组(单个字符串)
#如果有多个参数,则返回多个子组构成的元组,如果grou参数0,则返回结果是完整的匹配字符串
import re
str1 = 'xue.pro-8@gmail.com,please'
m = re.search(r'([\w.-]+)@([\w.-]+)', str1)
if m:
    print(m.group())
    print(m.group(1))
    print(m.group(2))
    print(m.group(1, 2))
    print(m.group(0))

'''
运行结果如下:
xue.pro-8@gmail.com
xue.pro-8
gmail.com
('xue.pro-8', 'gmail.com')
xue.pro-8@gmail.com
'''

groups的用法

#match.groups(default=None) #返回和模式串中从1开始的所有分组匹配的所有子组的元组(tuple)对象
import re
m = re.match(r'(\d+).(\d+)','24.1632')
print(m.groups())
运行结果如下:
('24', '1632')

标志参数

re模块的模式匹配函数或RegexObject的模式匹配方法通常有一个可选的标志参数(flags),用于对模式匹配进行不同的控制,这个标志参数默认值是0,也可以是不同标志通过’或’运算的组合

re.I或re.IGNORECASE:忽略大小写
re.M或re.MULTILING:控制开始/结束的元字符{^,$}对每一行还是整个文本(多行,re.MULTILINE)都起作用
re.S或re.DOTALL:使元字符对每一行都起作用
re.U或re.UNICODE:根据Unicode字符集解释字母,此标志会影响\w,\W,\b,\B,的行为,
re.L或re.LOCALE:根据当前区域设置解释单词,此解释会影响字母组(\w和\W)及字边界行为(\b和\B)
re.X或re.VERBOSE:该标志通过灵活的形式将正则表达式写得更易于理解,当该标志被指定时,在模式串中的空白符被忽略,除非该空白符在字符集中或在反斜杠后,它也可以允许将注释写入re模块,这些注释会被忽略,注释用#来标识,但该符号不能在字符串或反斜杠之后 
ss = """abc
def
ghi"""
r1 = re.findall(r"^\w", ss)
r2 = re.findall(r"^\w", ss, flags=re.MULTILINE)

print(r1)
print(r2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值