一、概述
字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。
正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
二、正则表达式的匹配规则
在我们使用正则表达式之前,我们需要首先了解正则表达式的一些匹配规则,具体的规则如下:
###1.匹配单个字符
字符 功能
. 匹配任意1个字符(除了\n)
[ ] 匹配[ ]中列举的字符
\d 匹配数字,即0-9
\D 匹配非数字,即不是数字
\s 匹配空白,即 空格,tab键,换行符\n
\S 匹配非空白
\w 匹配单词字符,即a-z、A-Z、0-9、_
\W 匹配非单词字符
示例:
ret =re.match('.','mll')
print(ret.group()) #m
ret3 = re.match('[hH]','hello world')
print(ret3.group()) #h
ret7 = re.match('\d\d\d', '44033')
print(ret7.group()) #440
2.匹配多个字符
字符 功能
* 匹配前一个字符出现0次或者无限次,即可有可无
+ 匹配前一个字符出现1次或者无限次,即至少有1次
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前一个字符出现m次
{m,n} 匹配前一个字符出现从m到n次
示例:
ret8 = re.match('[A-Z][a-z]*','M')
print(ret8.group())#M
ret9 = re.match('[A-Z][a-z]+','Ma')
print(ret9.group()) #Ma
3.匹配开头结尾
字符 功能
^ 匹配字符串开头
$ 匹配字符串结尾
示例:
ret10 = re.match('^[A-Z][0-9]*','M123456')
print(ret10.group()) #M123456
4. 匹配分组
字符 功能
| 匹配左右任意一个表达式
(ab) 将括号中字符作为一个分组
\num 引用分组num匹配到的字符串
(?P<name>) 分组起别名
(?P=name) 引用别名为name分组匹配到的字符串
示例:
#11.匹配出163、126、qq邮箱
emails = ['chen@163.com','chenzhen@126.com','1920939@qq.com','_222ddh@163.com','33@163.com.cn']
for email in emails:
ret19 = re.match('\w{4,20}@(163|126|qq)\.com$',email)
if ret19:
print('合法的邮箱:',ret19.group())
else:
print('不合法:',email)
输出结果如下:
合法的邮箱: chen@163.com
合法的邮箱: chenzheng@126.com
合法的邮箱: 1920939@qq.com
合法的邮箱: _222ddh@163.com
不合法: 33@163.com.cn
三、re模块
Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用\转义,因此我们强烈建议使用Python的r(表示原生的字符串)前缀,就不用考虑转义的问题了。
1. re.match()
re.match()能够匹配出以xxx开头的字符串,在上面第二节,我们基本使用的全部是这个模块。它返回的是一个Match对象,我们可以通过它的group()方法取出匹配的值。
ret8 = re.match('[A-Z][a-z]*','M')
print(ret8.group()) #M
2. re.search()
re.search()可以查询字符串中包含的值,返回的也是一个Match对象,我们可以通过它的group()方法取出匹配的值。
ret = re.search(r"\d+", "阅读次数为 9999")
ret.group() #9999
3. re.findall()
re.findall()可以查询字符串中所有符合要求的值,返回的是一个list
re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret) #['9999', '7890', '12345']
4. re.sub()
re.sub() 可以将匹配到的数据进行替换,返回的是替换后的字符串。
ret28 = re.sub(r'\d+','1200','python = 998')
print(ret28)
5. re.split()
re.split() 根据匹配进行切割字符串,并返回一个list
info = 'info:xiaoZhang 33 shandong'
ret31 = re.split(r':| ',info)
print('啦啦',ret31)