一、正则表达式
正则表达式就是做字符串匹配的一种工具,很多语言都支持正则表达式。
python中通过re模块中提供的方法来使用正则。
re.fullmatch(正则表达式,字符串) -- 完全匹配,检查字符串是否完全符合正则的要求
如果不匹配结果是None,匹配结果是匹配对象。
python正则表达式 -- r'正则'
JS正则表达式 -- /正则/
普通字符
普通字符在正则中代表字符本身,例如:a,b,c,1
1、第一类匹配字符的符合
1、. 一个点匹配一个任意字符
re_s = r'a.c'
# 匹配字符串有三个字符,第一个是a,第二个任意字符,第三个是c
result = re.fullmatch(re_s, 'avc')
print(result)
3、\w(匹配字母、数字、下划线) 一个字符
注意:这个不严谨,还可以匹配中文等字符。(Unicode中除了Asscll以外的字符)
不能匹配ASSII码中除了字母、数字、下划线以外的符合,
re_s = r'\wabc'
# 匹配一个字符串第一个字符是字母数字下划线,后面的是字母abc
rs = re.fullmatch(re_s, '你abc')
print(rs)
4、 \s 匹配空白字符
空白字符:空格、\t、\n -- 代码中\t只是一个长度,直接按tab是四个长度
一个\s只能匹配一个空白字符
re_s = r'...\s\s...'
# 匹配一个长度是8的字符,要求前三个字符是任意字符,中间两个空白,后面三个任意字符。
res = re.fullmatch(re_s, 'afs 8u-')
print(res)
5、\d(匹配数字字符)
re_s = r'\d\dabc'
res = re.fullmatch(re_s,'98abc')
print(res)
'''
6、\W(非数字、字母、下划线)
7、\S(非空白字符)
匹配一个长度是4的字符,第一个非空白字符,后三个是abc
re_s = r'\Sabc'
print(re.fullmatch(re_s,'oabc'))
8、\D(匹配非数字字符)
re_s = r'\Dabc'
print(re.fullmatch(re_s,'oabc'))
9、[](匹配字集中的一个字符)
a.[字符集] -- 匹配字符集中的任意一个字符
b.[字符1-字符2] -- 匹配字符1到字符2中的任意一个字符(要求字符1的编码值小于字符2)
[0-9] -- 匹配所有数字
[a-z] -- 匹配所有小写字母
[A-Z] -- 匹配所有大写字母
[a-zA-Z] -- 匹配所有字母
[\da-zA-Z_] -- 匹配字母数字下划线
[\u4e00-\u9fa5] -- 匹配所有中文
注意:一个[]只能匹配一个字符
# 匹配一个长度是4的字符,字符第一个字母是xyz中的一个,后面三个是abc
re_s = r'[xyz]abc'
print(re.fullmatch(re_s, 'xabc'))
re_s1 = r'[\dxyz]abc'
print(re.fullmatch(re_s1, '0abc'))
re_s2 = r'[2-8]abc'
print(re.fullmatch(re_s2, '4abc'))
re_s3 = r'[A-Za-z]abc'
print(re.fullmatch(re_s3, '4abc'))
10、[^]
[^字符集] -- 匹配不在字符集中的任意一个字符
[^\u4e00-\u9fa5] -- 匹配非中文
re_s4 = r'[^\u4e00-\u9fa5]abc'
print(re.fullmatch(re_s4, '胡abc'))
第二类检测
1、\b(检测单词边界)
\b所在的位置是否是单词边界
单词边界 -- 字符串开头或者结尾、空白、标点符号等
匹配一个长度是4的字符串,第一个字符是任意字符,后边是abc;
检查c的后面是否是单词边界
re_s5 = r'.abc\b'
print(re.fullmatch(re_s5, '8abc'))
2、^(用来检查是否是字符串开头)
3、$(检测是否是字符串结尾)
3转义符合
转义符合:在有特殊功能、有意义的符合前加“\”,让这个正则符合变成普通符合
注意:除了^放在[]开头,和-放在两个字符之间,其他单独的特殊符合,
在[]没有特殊功能都是表示字符本身
print(re.fullmatch(r'\d\d[.]\d\d', '00.89')) #匹配成功
^ 在[]中不是在开头,就没有特殊功能
- 在[]中只要不是放在两个字符之间,就代表-本身。
4、匹配次数
1、(匹配0次或多次)
字符 -- 指定的字符出现0次或多次
a* -- 字符a匹配0次或者多次
\d* -- 数字匹配0次或多次
[a-z]* -- 小写字母匹配0次或多次
print(re.fullmatch(r'a*bc', 'bc'))
print(re.fullmatch(r'a*bc', 'aaaaaaaaabc'))
2、+ (匹配一次或多次)
print(re.fullmatch(r'a\d+b', 'a0b'))
print(re.fullmatch(r'a\d+b', 'a098978b'))
print(re.fullmatch(r'a\d\d*b', 'a025b'))
3、?(0次或1次)
练习:写一个正则表达式,能够匹配一个整数
print(re.fullmatch(r'[-+]?\d*', '-70'))
print(re.fullmatch(r'-?\d*', '-70'))
4、{ }
{N} -- 匹配N次
{M,N} -- 匹配至少M次,最多N次
{M,} -- 匹配至少M次
{,N} -- 匹配最多N次
print(re.fullmatch(r'a{3}', 'aaa'))
print(re.fullmatch(r'\d{3,7}', '8609'))
print(re.fullmatch(r'\d{3,}', '8609555555555555555'))
print(re.fullmatch(r'\d{,7}', ''))
print(re.fullmatch(r'\d{,}', '8655555555555509'))
5、非贪婪
贪婪 -- 匹配次数不确定的时候,尽可能多的匹配 (上面次数不确定的符合都是贪婪的方式匹配)
非贪婪 -- 匹配次数不确定的时候,尽可能少的匹配(上面次数不确定的符合后面加?就会变成非贪婪)
*? -- 0次或多次,尽可能少
+? -- 一次或多次,尽可能少
?? -- -次或1次,尽可能少
{N,m}?
{M}?
{,N}?
5、分支和分组
1、|(分支)
正则1|正则2 -- 先用正则1匹配,如果匹配失败再用正则2匹配。(正则1和正则2中只要有一个成功就成功,两个都失败才失败)。如果正则1匹配成功,不会使用正则2匹配。
2、()分组
将部分表达式作为一个整体
1)整体区分
2)整体操作
r'(abc|xyz)123', 'abc123'
3)整体重复
\M -- 重复前面第M个分组匹配到的内容
print(re.fullmatch(r'abc123|xyz123', 'abc123'))
print(re.fullmatch(r'(abc|xyz)123', 'abc123'))
print(re.fullmatch(r'(\d\d)abc(\1){3}', '23abc232323'))
二、正则的方法
1、compile(正则表达式) -- 创建正则表达式对象
re_str = r'\d{3}'
re_obj = compile(re_str)
print(re_obj.fullmatch('999'))
2、fullmatch -- 完全匹配
fullmatch(正则表达式,字符串) -- 让正则和字符串完全匹配。
匹配失败返回None,匹配成功返回匹配对象。
对整个字符串进行检查的时候用,比如判断账号、密码时候合法
print(fullmatch(r'\d{3}[a-z]{2}[A-Z]{3}','980sjKLJ'))
3、match -- 匹配字符串开头
match(正则表达式,字符串) -- 让正则表达式和字符串开头匹配;匹配失败返回None,匹配成功返回匹配对象。
print(match(r'\d{3}[a-z]{2}[A-Z]{3}', '983lkZKGgagagafafaf'))
print(match(r'aa[a-z]{2}','aaakhsgafrgaerga4trqwr4w3rafawyag'))
4、search -- 字符串查找
search(正则表达式,字符串) -- 在字符串中找到第一个和正则匹配的子串;匹配失败返回None,匹配成功返回匹配对象。
print(search(r'\d{3}', '98340iafjoa4455jf'))
通过匹配对象能获取到一下内容:
1)匹配结果
匹配对象.group
匹配对象.group() # 获取整个正则匹配到的结果
匹配对象.group(1) # 获取匹配对象的第一个分组
2)匹配范围(被匹配到的内容在原字符串中的范围)
匹配对象.span()
匹配对.start()
匹配对象.end()
匹配对象.string() # 获取原字符串
a = fullmatch(r'(\d{2})(a{2})','99aa')
print(a.group(1))
5、split -- 字符串切割
split(正则表达式,字符串,切割次数) -- 将字符串按照满足正则的子串切割;返回的是列表,列表是被切开的子串。
切割次数 -- 不传参就全切
print(split(r'\d+', 'air453to3kj46o3itjwa8jt3woig0wgqihtgoi4wjt'))
6、sub -- 字符串替换
sub(正则,替换的新字符串,原字符串,替换次数) -- 将原字符串中满足正则的字符串,替换成新串
替换次数 -- 不传参就全都替换
print('fj99agjg49aaf9agj9a999fafaf99faf99agag99ag'.replace('a','o'))
print(sub(r'\d+','+','fj99agjg49aaf9agj9a999fafaf99faf99agag99ag'))
print(sub(r'\d','+','fj99agjg49aaf9agj9a999fafaf99faf99agag99ag'))
7、findall -- 查找所有
findall(正则,字符串) -- 在字符串中查找所有满足正则的字符串,然后以列表的形式返回
注意:使用findall的时候,如果有分组想要取整个正则匹配的结果是取不到的(如果在正则中需要)
print(findall(r'\d+o', '63o634609ogj39yj30ojyb043nyjb430ogy3f'))
print(findall(r'(\d+)o', '63o634609ogj39yj30ojyb043nyjb430ogy3f'))
print(findall(r'(\d+)([a-z]{3})', '63o634609ogj39yj30ojyb043nyjb430ogy3f'))
8、finditer -- 查找所有
finditer(正则,字符串) -- 在字符串中查找所有满足正则的子串;返回的一个迭代器,元素是每个子串对应的
a = finditer(r'\d{2}','44jj55kk66lkj7l7njkn88')
for i in a:
print(i)
print(i.group())