正则表达式基础
一、初识正则表达式
思考–问题答案在文末
- 问题1:text1 = ‘height:178,weight:168,sid:123456,passwd:9527’,如何快速找出密码?
- 问题2:text2 = ‘他的电话是18812345678x,他的生日是20000908,他爱好的数字是01234567891,他的座机是:0571-52152166’,如何快速匹配座机?
- 问题3:text3 = ‘1234567@qq.com’ ,如何检测邮箱格式是否正确?
Q1:什么是正则表达式?
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
Q2:他有什么用处?
- 判断给定的字符串是否符合正则表达式的过滤逻辑(验证):(验证:登录信息、手机号、邮箱地址)
- 可以通过正则表达式,从字符串中获取我们想要的特定部分(匹配)
常见匹配字符
符号 | 描述 |
---|---|
. | 匹配处换行符\n之外任意1个字符 |
[] | 匹配[]中任意一个 |
\d | 一个0-9数字 |
\D | 匹配非数字 |
\w | 匹配单词字符:a-z、A-Z、0-9 |
\W | 匹配非单词字符 |
\s | 匹配空格、tab健 |
\S | 匹配非空格,tab健 |
常用的匹配规则-匹配字符数量
-
匹配前一个字符出现0次或者无数次
-
匹配前一个字符出现1次或者无数次
符号 | 描述 |
---|---|
? | 匹配前一个字符出现0次或者1次 |
{m} | 匹配前一个字符出现m次 |
{m,} | 匹配前一个字符出现至少m次 |
{n,m} | 匹配前一个字符出现n-m次 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
| | 或 |
(ab) | 将括号中字符作为一个分组 |
二、 python正则表达式处理模块----re
2.1re.match函数----对字符串进行匹配
#re.match()函数,可以对字符进行匹配,查找的位置是从指定的位置开始一直往后找,返回第一个符合规则的对象,如果开始位置不符合匹配队形则返回None。而如果从起始位置开始没有匹配成功,即便其他部分包含需要匹配的内容,re.match()也会返回None。
import re
#基本的语法格式:match(pattern,string,flags=0)
#其中第一个参数是需要进行匹配的内容,第二个参数表示的是一个匹配的字符串,最后一个参数这是一个控制正则表达式的匹配方式,是一个可选的参数,
s1 = 'height:178 weight:168,sid:123456,passwd:9527'
re2 = re.match('[a-zA-Z]+\W\d+\s\w+',s1)
print(re2)
s = "python is the bset language"
re1 = re.match('(.*)\s(\w+)\s(\w+)(\s\w+)(\s\w+)',s)
print(re1)
print(re1.group())
print(re1.group(1))
print(re1.group(2))
print(re1.group(3))
print(re1.span())
*******************print*********************************
<re.Match object; span=(0, 17), match='height:178 weight'>
<re.Match object; span=(0, 27), match='python is the bset language'>
python is the bset language
python
is
the
(0, 27)
2.2 re.findall()
findall匹配所有返回一个列表,这个方法使用频率较高。
import re
text = 'height:178,weight:168,sid:123456,passwd:9527'
print(re.findall(r'[a-zA-Z]+',text))
text2 = '12232443@qq.com'
print(re.findall(r'\d{6,10}@qq.com',text2))
text3 = 'syyang2022@163.com'
print(re.findall(r'\w+@\w+.\w{2,3}$',text3))
#print(re.findall(r'^[a-zA-Z-_]+@[a-zA-Z-_]+.[a-zA-Z-_]+',text3))
text4 = '10.10.10.10'
print(re.findall(r'\d{1,3}.\d+.\d+.\d+',text4))
#print(re.findall('\D+',text))
*******************print*********************************
['height', 'weight', 'sid', 'passwd']
['12232443@qq.com']
['syyang2022@163.com']
['10.10.10.10']
2.3 re.search方法
re.search 扫描整个字符串并返回第一个成功的匹配。search 在全文中匹配一次,匹配到就返回 函数语法: re.search(pattern, string, flags=0) 示例: 输出结果: searchObj.group() : Cats are smarter than dogs searchObj.group(1) : Cats searchObj.group(2) : smarter
import re
s = "Cats are smarter than dogs"
re2 = re.search('are',s)
print(re2)
print(re2.group())
*******************print*********************************
<re.Match object; span=(5, 8), match='are'>
are
2.4 re.sub()
检索和替换 re.sub()将匹配到的数据进行替换。 语法:re.sub(pattern, repl, string, count=0, flags=0) 示例: 输出结果: 电话号码是: 2019-0101-000 电话号码是 : 20190101000
import re
s = "python is the bset language"
re2 = re.sub('p','P',s,count=1)
print(re2)
s = "2019-0101-000"
re2 = re.sub('-','',s,count=0)
print(re2)
*******************print*********************************
Python is the bset language
20190101000
2.5 re.compile
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供其他函数使用,我们常用的正则表达式方法,都已经自带了compile了。 语法格式为: re.compile(pattern[, flags]) 示例: 输出结果: None <_sre.SRE_Match object; span=(3, 5), match=‘12’> 12
s1 = 'height:178,weight:168,sid:123456,passwd:9527'
pattern = "\d*"
re2 = re.match(pattern,s1)
print(re2)
*******************print*********************************
<re.Match object; span=(0, 0), match=''>
2.6 re.split()
split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下: re.split(pattern, string[, maxsplit=0, flags=0]) 示例: 输出结果: [‘www’, ‘huawei’, ‘com’]
import re
text = 'www.huawei.com'
print(re.split('w',text,))
print(re.split('\.',text))
*******************print*********************************
['', '', '', '.hua', 'ei.com']
['www', 'huawei', 'com']
三、写正则表达式的步骤
我们仍然以包含分机号码的座机电话号码为例,比如0571-88776655-9527,演示下面的步骤:
确定模式包含几个子模式
它包含3个子模式:0571-88776655-9527。这3个子模式用固定字符连接。
各个部分的字符分类是什么
这3个子模式都是数字类型,可以用\d。现在可以写出模式为:
\d-\d-\d
各个子模式如何重复
第1个子模式重复3到4次,因为有010和021等直辖市
第2个子模式重复7到8次,有的地区只有7位电话号码
第3个子模式重复3-4次
加上次数限制后,模式成为:
\d{3,4}-\d{7,8}-\d{3,4}
但有的座机没有分机号,所以我们用或运算符让它支持两者:
\d{3,4}-\d{7,8}-\d{3,4}|\d{3,4}-\d{7,8}
是否有外部位置限制
没有
是否有内部制约关系
没有
经过一通分析,最后的正则就写成了,测试一下:
import re
text = '18812345678是他的手机号,他的身份证号是41188123456780978,他爱好的数字是01234567891,他的座机是:0571-52152166'
print(re.findall(r'^1\d{10}|\d{4}-\d{8}', text))
*******************print*********************************
['18812345678', '0571-52152166']
掌握常见匹配符合及规则就够日常使用
四、4个问题答案
-
问题1:text1 = ‘height:178,weight:168,sid:123456,passwd:9527’,如何快速找出4位数字密码?
import re text1 = 'height:178,weight:168,sid:123456,passwd:9527' print(re.findall(r'\d{4}$',text1)) *******************print********************************* ['9527']
-
问题2:text2 = ‘他的电话是18812345678x,他的生日是20000908,他爱好的数字是01234567891,他的座机是:0571-52152166’,如何快速匹配座机?
import re text2 = '他的电话是18812345678x,他的生日是20000908,他爱好的数字是01234567891,他的座机是:0571-52152166' print(re.findall(r'\d{4}-\d{8}',text2)) *******************print********************************* ['0571-52152166']
-
问题3:text3 = ‘1234567@qq.com’ ,如何检测qq邮箱格式是否正确?
import re text3 = '1234567@qq.com' print(re.findall(r'\d{6,10}@\w+.\w{2,3})',text3)) *******************print********************************* ['1234567@qq.com']
日常笔记,共勉