正则表达式
1.在实际开发过程中经常会有查找符合某些复杂规则的字符串的需要,比如:邮箱、图片地址、手机号码等,
这时候想匹配或者查找符合某些规则的字符串就可以使用正则表达式了。
- 正则表达式概念
正则表达式就是记录文本规则的代码
3.正则表达式的特点
1. 正则表达式的语法很令人头疼,可读性差
2. 正则表达式通用行很强,能够适用于很多编程语言
4.re模块介绍
简单代码:
导入re模块
import re
使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
re模块的使用
简单代码:
import re
使用match方法进行匹配操作
result = re.match("itcast","itcast.cn")
info = result.group()
print(info)
运行结果:
itcast
#1. re.match() 根据正则表达式从头开始匹配字符串数据
- 匹配单个字符串
代码 功能
. 匹配任意1个字符(除了\n)
[ ] 匹配[ ]中列举的字符
\d 匹配数字,即0-9
\D 匹配非数字,即不是数字
\s 匹配空白,即 空格,tab键
\S 匹配非空白
\w 匹配非特殊字符,即a-z、A-Z、0-9、_、汉字
\W 匹配特殊字符,即非字母、非数字、非汉字
示例代码:
# .
import re
ret = re.match('.','M')
print(ret.group())
ret = re.match('t.o','too')
print(ret.group())
ret = re.match('t.o','two')
print(ret.group())
# []
# 如果hello的首字母小写,那么正则表达式需要小写的h
ret = re.match('h','hello python')
print(ret.group())
# 如果hello的首字母大写,那么正则表达式需要大写的H
ret = re.match('H','Hello python')
print(ret.group())
# 大小写h都可以的情况
ret = re.match('[hH]','hello python')
print(ret.group())
ret = re.match('[hH]','Hello python')
print(ret.group())
ret = re.match('[hH]ello Python','hello Python')
print(ret.group())
ret = re.match('[0-9]Hello python','7Hello python')
print(ret.group())
ret = re.match('[0-35-9]Hello Python','7Hello Python')
print(ret.group())
# 这个正则不能够匹配到数字4,因此ret为None
ret = re.match('[0-35-9]Hello python','4Hello python')
print(ret)
# \d
ret = re.match('嫦娥1号','嫦娥1号发射成功')
print(ret.group())
ret = re.match('嫦娥2号','嫦娥2号发射成功')
print(ret.group())
ret = re.match('嫦娥3号','嫦娥3号发射成功')
print(ret.group())
ret = re.match('嫦娥\d号','嫦娥1号发射成功')
print(ret.group())
ret = re.match('嫦娥\d号','嫦娥2号发射成功')
print(ret.group())
ret = re.match('嫦娥\d号','嫦娥3号发射成功')
print(ret.group())
# 这个正则不能够匹配到正确的,因此ret为None
ret = re.match('嫦娥\d号','嫦娥a号发射成功')
print(ret)
# \D
# 这个正则不能够匹配到正确的,因此ret为None
ret = re.match('嫦娥\D号', '嫦娥1号发射成功')
print(ret)
ret = re.match('嫦娥\D号', '嫦娥a号发射成功')
print(ret.group())
# \s
# 空字符串并不是空白字符串所以这个也是错的
print(re.match('\s',''))
# 这两个是对的
print(re.match('\s',' '))
print(re.match('\s','\n'))
# 这两个正则不能够匹配到正确的,因此ret为None
print(re.match('\s','a'))
print(re.match('\s','a '))
# \S
print(re.match('\S',''))
print(re.match('\S',' '))
print(re.match('\S','\n'))
print(re.match('\S','\t'))
print(re.match('\S','a'))
# 空字符串并不是空白字符串也不是所以这两个都是报None
print(re.match('\S',''))
print(re.match('\s',''))
# \w
print(re.match('\w','d'))
print(re.match('\w','D'))
print(re.match('\w','5'))
print(re.match('\w','_'))
# & 和 空白 不属于字母,数字,汉字和下划线点
print(re.match('\w','&'))
print(re.match('\w',' '))
# \W
print(re.match('\W','d'))
print(re.match('\W','D'))
print(re.match('\W','5'))
print(re.match('\W','一'))
print(re.match('\W','_'))
# & 和 空白 属于特殊字符可以成功运行 ,其他的都是报None
print(re.match('\W','&'))
print(re.match('\W',' '))
- 匹配多个字符
匹配多个字符
代码 功能- 匹配前一个字符出现0次或者无限次,即可有可无
-
匹配前一个字符出现1次或者无限次,即至少有1次
{m} 匹配前一个字符出现m次
{m,n} 匹配前一个字符出现从m到n次
匹配多个字符的符号需要和匹配单个的字符组合使用,单独使用无意义
# * 匹配前一个字符出现0次或者无限次,即可有可无
print(re.match('\w*','a'))
print(re.match('\d*','a'))
print(re.match('[a1]*','a'))
print(re.match('\d*','1234567a2365'))
# + 匹配前一个字符出现1次或者无限次,即至少有1次
print(re.match('\w+','a'))
print(re.match('\d+','a'))
print(re.match('[a1]+','a')) -----> None
print(re.match('\d+','123456a456'))
# ? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
print(re.match('\d?','1'))
print(re.match('\d?','a'))
print(re.match('\d?','1234'))
print(re.match('\d?',' '))
# {m}
print(re.match('.{2,4}','1'))
print(re.match('.{2,4}','1234'))
print(re.match('.{2,4}','12345'))
print(re.match('.{2}','1'))
print(re.match('.{2}','12'))
print(re.match('.{2}','123'))
# 至少匹配m个
print(re.match('.{2,}','1'))----->None
print(re.match('.{2,}','12'))----->12
print(re.match('.{2,}','123'))---->123
print(re.match('.{2,}','1234'))---->1234
# 匹配一个座机电话
print(re.match('\d{3,4}-\d{7,8}','010-8888888'))
print(re.match('\d{3,4}-\d{7,8}','021-77777777'))
print(re.match('\d{3,4}-\d{7,8}','022-666666'))
print(re.match('\d{3,4}-\d{7,8}','0451-8888888'))
print(re.match('\d{3,4}-\d{7,8}','9876-1234566'))
print(re.match('\d{3,4}-\d{7,8}','0451-0234566'))
# ('0\d{2,3} ----> 表示是以0开头
print(re.match('0\d{2,3}-[1-9]\d{6,7}','9876-1234566'))
print(re.match('0\d{2,3}-[1-9]\d{6,7}','0451-0234566'))
7. 匹配开头和结尾
代码 功能
^ 匹配字符串开头
$ 匹配字符串结尾
# ^ 匹配字符串开头
print(re.match('^\d+','1'))
print(re.match('^\d+','23456'))
print(re.match('^\d+','a123456'))
# [^] [^指定字符]: 表示除了指定字符都匹配
print(re.match('[^\d]+','1'))----->None
print(re.match('[^\d]+','23456'))----->None
print(re.match('[^\d]+','a'))
print(re.match('[^\d]+','aa'))
print(re.match('[^\d]+','222'))----->None
# ^[^] 以 除指定字符开头的规则
print(re.match('^[^\d]+','1abcd'))----->None
print(re.match('^[^\d]+','abcd1'))
# $ 匹配字符串结尾
print(re.match('\d$','1'))
print(re.match('.*\d$','asd1'))--->加上.*可以匹配上前面是字母
print(re.match('\d$','1aaa'))----->None
print(re.match('\d$','asd1'))----->None
print(re.match('\d$',' 12a45'))----->None
8.匹配分组
代码 功能
| 匹配左右任意一个表达式
(ab) 将括号中字符作为一个分组
\num 引用分组num匹配到的字符串
(?P) 分组起别名
(?P=name) 引用别名为name分组匹配到的字符串
# | 匹配左右任意一个表达式
print(re.match('[a-z]|[A-Z]ython','Python'))
print(re.match('[a-z]|[A-Z]ython','python'))
print(re.match('[a-z]|[A-Z]ython','jython'))
print(re.match('[a-z]|[A-Z]ython','1ython'))--->None
print(re.match('[a-z]|[A-Z]ython','a'))
# (|)
print(re.match('([a-z]|[A-Z])ython','Python'))
print(re.match('([a-z]|[A-Z])ython','python'))
print(re.match('([a-z]|[A-Z])ython','jython'))
print(re.match('([a-z]|[A-Z])ython','1ython'))--->None
print(re.match('([a-z]|[A-Z])ython','a'))--->None
# (ab) 将括号中字符作为一个分组
# 匹配一个邮箱是否是QQ.com/163.com/sina.com
print(re.match('[a-zA-Z0-9_]{4,8}@(qq|163|sina).com','123456@qq.com'))
print(re.match('[a-zA-Z0-9_]{4,8}@(qq|163|sina).com','123456@163.com'))
print(re.match('[a-zA-Z0-9_]{4,8}@(qq|163|sina).com','123456@sina.com'))
print(re.match('[a-zA-Z0-9_]{4,8}@(qq|163|sina).com','123456@qq'))--->None
print(re.match('[a-zA-Z0-9_]{4,8}@(qq|163|sina).com','123456@qq.com.com'))--->这个有缺陷有意这个也会输出成功
# (ab)
match_obj = re.match("[a-zA-Z0-9_]{4,20}@(163|126|qq|sina|yahoo)\.com",'hello@163.com')
print(match_obj.group())--->hello@163.com
print(match_obj.group(1))--->163
简单代码:
需求: 匹配qq:10567这样的数据,提取出来qq文字和qq号码
import re
match_obj = re.match("(qq):([1-9]\d{4,10})", "qq:10567")
if match_obj:
print(match_obj.group())
# 分组:默认是1一个分组,多个分组从左到右依次加1
print(match_obj.group(1))
# 提取第二个分组数据
print(match_obj.group(2))
else:
print("匹配失败")
执行结果:
qq
10567
# \num
ret = re.match('<[a-zA-Z0-9]+>(.*)</[a-zA-Z0-9]+>','<div>皮鞋皮鞋</div>')
print(ret)
# ret = re.match('<[a-zA-Z0-9]+>(.*)</[a-zA-Z0-9]+>','<div>皮鞋皮鞋</p>')
ret = re.match('<([a-zA-Z0-9]+)>(.*)</\\1>','<div>皮鞋皮鞋</p>')
print(ret)
# r'' 正则表达式中的原生字符串,表示在字符串中的字符都是普通字符,无特殊意义
ret = re.match(r'<([a-zA-Z0-9]+)>(.*)</\1>','<div>皮鞋皮鞋</div>')
print(ret)
print(ret.group(2))
\1 是把‘\’给转义了
\1 的作用是 引用前面分组的规则,1指的是分组的编号,
r 表示的是正则表达式中的原生字符串,把特殊字符串转换成无意义的省的转义了
# (?P<name>) 分组起别名
# (?P=name) 引用别名为name分组匹配到的字符串
# 为分组设置名 (?P<name>) 通过分组名获取分组 (?P=name)
ret = re.match(r'<([a-zA-Z0-9]+)>(.*)</\1>','<div>皮鞋皮鞋</div>')
print(ret)
print(ret.group(2))
|
|
V
ret = re.match(r'<(?P<mk>[a-zA-Z0-9]+)>(.*)</(?P=mk)>','<div>皮鞋皮鞋</div>')
print(ret)
print(ret.group(2))
re.match('\w+@\w+\.\w+')
9.正则高级函数
- findall() 在指定字符串中去匹配相应的规则
- sub 替换字符串,在指定的字符串中,使用指定的子串,替换满足规则的字符串
- split 分割字符串
# match 表示从头开始
ret = re.match('\d+','销量:888 库存:9999')
print(ret)
# search 在指定字符串中去匹配相应的规则,如果有多个子串满足规则时,
# 返回第一个满足的子串
ret = re.search('\d+','销量:888 库存:9999')
print(ret)
# findall() 表示在指定字符串中去匹配相应的规则,返回所有满足的子串,结果是一个列表
ret = re.findall('\d+','销量:888 库存:9999')
print(ret)
# sub 替换字符串,在指定的字符串中,使用指定的字串,替换满足规则的字符串
ret = re.sub('\d+','$$$','销量:888 库存:99999')
print(ret)
ret = re.sub('p','div','<p>xxpxx</p>')
print(ret)
ret = re.sub('<p>','<div>','<p>xxxx</p>')
print(ret)
ret = re.sub('</p>','</div>',ret)
print(ret)
# split 分割字符串
ret = re.split(r'|,|\.','hello world,python:java.c++')
print(ret)
s = '__'.join(ret)
print(s)