re(正则表达式)
1、普通字符:大多数字符和字母都会和自身匹配
import re
# 前一段字符串为匹配规则,后一段字符串为要匹配的字符串
ret = re.findall('adc','youareagoodadcpreson')
print(ret)# ['adc']
2、元字符:. ^ $ * + ? {} [] \ () |
2-1 . ^ $ * + ? {}
import re
# . 代表一个字符除了'\n'
ret1 = re.findall('a..d', 'helloabcdefg')
ret2 = re.findall('a..d', 'helloabdefg')
print(ret1,ret2)# ret1匹配成功['abcd'],ret2匹配失败[]
# ^ 代指字符串的开头
ret1 = re.findall('^a..d', 'abcdef')
ret2 = re.findall('^a..d', 'qabcdef')
print(ret1, ret2)# ret1匹配成功['abcd'],ret2匹配失败[]
# $ 代指字符串的结尾
ret1 = re.findall('a..d$', 'qwerabcd')
ret2 = re.findall('a..d$', 'qwerabcdef')
print(ret1, ret2)# ret1匹配成功['abcd'],ret2匹配失败[]
# * 紧挨的字符重复0--无穷次
ret1 = re.findall('ra*', 'qweraaaaabcd')
ret2 = re.findall('qwel*', 'qweraaaaabcd')
print(ret1, ret2)# ['raaaaa'] ['qwe']
# + 紧挨的字符重复1--无穷次
ret1 = re.findall('qwera+', 'qweraaaaabcd')
ret2 = re.findall('qwerb+', 'qwerabcdef')
print(ret1, ret2)# ['qweraaaaa'] []
# ?代表紧挨的字符匹配0--1次
ret1 = re.findall('qwera?', 'qweraaaaabcd')
ret2 = re.findall('qwerb?', 'qwerabcdef')
print(ret1, ret2)#['qwera'] ['qwer']
### 注意:前面的 + * ? 等都是贪婪匹配,也就是尽可能的匹配,后面加 ? 使其变为惰性匹配
ret = re.findall('qwera+?', 'qweraaaaabcd')
print(ret)# ['qwera']
# {0, } == *
# {1, } == +
# {0, 1} == ?
ret1 = re.findall('qwera{0,2}', 'qweraaaaabcd')
ret2 = re.findall('qwera{0,}', 'qweraaaaabcd')
print(ret1, ret2)# ['qweraa'] ['qweraaaaa']
2-2 字符集 []
import re
ret1 = re.findall('a[bc]d', 'qwacd')
ret2 = re.findall('a[bc]d', 'qwabcd')
ret3 = re.findall('a[bc]', 'qwa')
ret4 = re.findall('a[bc]*', 'qwa')
print(ret1, ret2, ret3, ret4)# ['acd'] [] [] ['a']
ret1 = re.findall('a[a-z]d', 'qwacd')
ret2 = re.findall('[a-z]', 'abcd')
print(ret1, ret2)# ['acd'] ['a', 'b', 'c', 'd']
ret = re.findall('a[.*+]', 'qwa.a*ca+d')
print(ret)# ['a.', 'a*', 'a+']
### 字符集中有功能的符号: - ^ \
ret = re.findall('[1-9]', '1ab3cd6f')
# 按ASCII码排列
print(ret)# ['1', '3', '6']
#在字符集中^代表非
ret1 = re.findall('[^1-9]', '123abc')
ret2 = re.findall('[^abc]', '123abc')
print(ret1, ret2)# ['a', 'b', 'c'] ['1', '2', '3']
ret = re.findall('[\d]', 'qwe231')
print(ret)# ['2', '3', '1']
2-3 转义字符 \
反斜杠后面跟元字符去除特殊功能,比如*
反斜杠后面跟普通字符实现特殊功能,比如\d
\d---匹配任何十进制数,相当于类[0-9]
\D---匹配任何非数字字符,相当于类[^0-9]
\s---匹配任何空白字符,相当于类[\t\n\r\f\v]
\S---匹配任何非空白字符,相当于类[^\t\n\r\f\v]
\w---匹配任何字母数字字符,相当于类[a-zA-Z0-9]
\W---匹配任何非字母数字字符,相当于类[^a-zA-Z0-9]
\b---匹配一个特殊字符边界,比如空格,&,#等
import re
a = 'i am good boy'
ret = re.findall('i\\b', a)# 模式字符串
print(ret)# []
ret = re.findall(r'i\b', a)# 原生字符串
print(ret)# ['i']
ret = re.findall(r'i\\l', 'i\lm')
print(ret)# ['i\\l']
由于模式字符串中可能包含大量的特殊字符和反斜杠,所以需要写为原生字符串,即在模式字符串前加 r 或 R.
2-4 分组 ()
import re
ret1 = re.findall(r'(ab)+', '123abbb')
print(ret1)# ['ab']
ret2 = re.findall('abc+', '123abc3abcabc')
print(ret2)# ['abc', 'abc', 'abc']
# 以abc为整体,返回值为abc
ret3 = re.findall('(abc)+', '123abcabcabc')
print(ret3)# ['abc']
# 优先返回分组里的内容
ret4 = re.findall('a(b|c)d', '1abd2acd3')
print(ret4)# ['b', 'c']
# 在 () 中加 ?: 取消权限
ret5 = re.findall('a(?:b|c)d', '1abd2acd3')
print(ret5)# ['abd', 'acd']
2-5 选择字符 |
| 表示或
import re
ret1 = re.findall('abc|d', '123abd')
print(ret1)# ['d']
ret2 = re.findall('abc|d', '123abc|d')
print(ret2)# ['abc', 'd']
ret3 = re.findall('ab(c|d)', 'abc123abd')
print(ret3)# ['c', 'd']
3、标志位
A or ASCII--->对于\w,\W,\b,\B,\d,\D,\s,\S只进行ASCII匹配
I or IGNORECASE--->执行不区分字母大小写的匹配
M or MULTILINE--->将^和$用于包括整个字符串的开始和结尾的每一行
S or DOTALL--->使用(.)字符匹配所有字符,包括换行符
X or VERBISE--->忽略模式字符串中为转移的空格和注释
4、re模块下的常用方法
4-1 re.findall(pattern, string, [flags])
pattern--模式字符串,rep--替换的字符串, string--被查找替换的原始字符串
(可选参数)flags--表示标志位,控制匹配方式
import re
# 满足所有匹配条件的结果,放在列表里
ret1 = re.findall('ab', 'abcabc')
print(ret1)# ['ab', 'ab']
4-2 re.search(pattern, string, [flags])
import re
# 整个字符串中搜索第一个匹配的值,匹配成功则返回Match对象,否则返回None
ret2 = re.search('ab', '123abcabc')
print(ret2)# <re.Match object; span=(3, 5), match='ab'>
ret3 = re.search('ab', '123abcabc').group()
print(ret3)# ab
# 匹配括号中的值赋予一个变量名()-->(?P<变量名>模式字符串)
ret3 = re.search(R'(?P<name>[a-z]+)\d+', 'abc123abc123abc').group()
print(ret3)# abc123
ret4 = re.search(R'(?P<name>[a-z]+)\d+', 'abc123abc123abc').group('name')
print(ret4)# abc
4-3 re.match(pattern, string, [flags])
同Search,但是仅在字符串开始处进行配对
import re
ret1 = re.match('1a', '1a2b3c')
print(ret1)# <re.Match object; span=(0, 2), match='1a'>
ret2 = re.match('2b', '1a2b3c')
print(ret2)# None
4-4 re.split(pattern, string, [maxsplit], [flags])
(可选参数)maxsplit--最大的拆分次数
import re
ret1 = re.split(' ', 'hello world !')
print(ret1)#['hello', 'world', '!']
# 分割字符左边无字符时为空
ret2 = re.split('[ |]', " hello every|world !")
print(ret2)#['', 'hello', 'every', 'world', '!']
4-5 re.sub(pattern, rep1, string, [count], [flags])替换字符串
rep--替换的字符串
(可选参数)count--替换的最大次数,默认为0
import re
ret1 = re.sub('\d', 'A', '123abc', 0)
print(ret1)# AAAabc
ret2 = re.sub('\d+', 'A', '12ab34cd', 1)
print(ret2)# Aab34cd
# 元组形式,包含匹配次数
ret3 = re.subn('\d+', 'A', '1a2b3c4d')
print(ret3)# ('AaAbAcAd', 4)
4-6 将模式字符串转换为正则表达式对象
import re
bj = re.compile('\d+')
ret = obj.findall('1a2b3c4d')# 好处:可以多次使用
print(ret)# ['1', '2', '3', '4']
4-7 re.findall() 与 re.finditer()
import re
# 所有结果封装到列表
ret1 = re.findall('\d', '1a2b3c')
print(ret1)# ['1', '2', '3']
# 返回迭代器对象
ret2 = re.finditer('\d', '1a2b3c')
print(ret2)# <callable_iterator object at 0x000001EC44F2CAC8>
print(next(ret2).group())# 1
print(next(ret2).group())# 2