本文为观看武sir《70分钟 搞定 正则表达式【含实战案例】》https://www.bilibili.com/video/av671083532?p=5&t=896的笔记
正则表达式
1. 字符相关
- 匹配文本中的一个字符串
import re
text = '很长的一段文本啦啦啦文本啦啦啦'
data_list = re.findall("文本",text)
print(data_list) # 文本
[abc]匹配a或者b或者c
import re
text = 'qaqbqc'
data_list = re.findall("q[abc]",text)
print(data_list) # ['qa', 'qb', 'qc']
[^abc]匹配除了abc以外的
import re
text = 'qaqbqcqd'
data_list = re.findall("q[^abc]",text)
print(data_list) # ['qd']
[a-z]匹配a-z任意字符,只匹配一个字母
import re
text = 'qAqbqfqg'
data_list = re.findall("q[a-f]",text)
print(data_list) # ['qb', 'qf']
.·代指换行符以外的任意字符+表示前面的字符出现1次或者n次?表示非贪婪匹配
import re
text = 'asdrqwerioqpowerpiaocasdjalksdlkjasldj'
data_list = re.findall("r.o",text)
print(data_list) # ['rio']
# 因为默认使用贪婪匹配,因此会把最长的匹配出来
data_list = re.findall("r.+o",text)
print(data_list) # ['rqwerioqpowerpiao']
# 加一个问号就变成非贪婪匹配
data_list = re.findall("r.+?o",text)
print(data_list) # ['rqwerio', 'rpiao']
-
\w代指字母或者数字或者下划线或者各国语言注意:\w是否能够匹配各国语言(双字节字符)视操作系统/编程环境而定,\w原本是能够匹配一个字母或数字或下划线(A~Z,a~z,0~9,_)中的任意一个。某些情况下,\w也会匹配本地字符集,比如中文系统的中文,全角数字等,所以在明确要求是A~Z,a~z,0~9,_ 中的一个的时候,用[A-Za-z0-9_],而不用\w
匹配中文字符的正则表达式:
[\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内):[^\x00-\xff]
import re
# 因为有空格,所以不会匹配到最后
text = 'UncleDongにほんご早上好coo l'
data_list = re.findall("U\w+l",text)
print(data_list) # ['Uncl']
# 因为变成了下划线,所以会匹配到最后
text = 'UncleDongにほんご早上好coo_l'
data_list = re.findall("U\w+l",text)
print(data_list) # ['UncleDongにほんご早上好coo_l']
\d代指数字
import re
text = 'root-123-sss12-1'
# 因为只有一个\d匹配,所以只会匹配单一的数字
data_list = re.findall("-\d",text)
print(data_list) # ['-1', '-1']
# 因为有了+,所以会匹配多个
data_list = re.findall("-\d+",text)
print(data_list) # ['-123', '-1']
\s代表任意的空白符,比如空格制表符
import re
text = 'root 123 sss12 1'
# 因为只有一个\d匹配,所以只会匹配单一的数字
data_list = re.findall("\d+\s+\w",text)
print(data_list) # ['-1', '-1']
2. 数量相关
*重复0次或者多次+重复1次或者多次?重复0次或者1次(出现在+后面是非贪婪匹配,出现在别的字符后面是0 or 1次){n}重复n次
import re
text = 'root 123 sss12 1'
# 匹配空格出现三次的。。有点无聊hhh
data_list = re.findall(" {3}",text)
print(data_list) # [' ']
{n,}重复n次或者更多次
import re
text = 'root 123 sss12 1'
# 空白字符匹配,这个更无聊了
data_list = re.findall(" {0,}",text)
print(data_list) # ['', '', '', '', ' ', '', '', '', ' ', '', '', '', '', '', ' ', '', '']
{n,m}重复n~m次
3. 分组
使用括号进行分组
- 提取数据区域
import re
text = '我的电话号码是09954323178'
data_list = re.findall("954\d{5}",text)
print(data_list) # ['95432317']
# 现在想按照这个规则匹配,但只想要中间的部分数据,这样就只会匹配出分组内的
data_list = re.findall("95(4\d{5})",text)
print(data_list) # ['432317']
# 括号的存在不影响匹配,只影响匹配的返回结果
text = '我的电话号码是09954323178,另一个号码是9954000000'
data_list = re.findall("(9)5(4\d{5})",text)
print(data_list) # [('9', '432317'), ('9', '400000')]
# 每有一个括号,返回就多一个东西
text = '我的电话号码是09954323178,另一个号码是9954000000'
data_list = re.findall("((9)5(4\d{5}))",text)
print(data_list) # [('95432317', '9', '432317'), ('95400000', '9', '400000')]
- 达到“或”的效果,括号内的匹配是或的关系
[abc]等价于(a|b|c),但是[]只支持一个字符的或,不支持多个的
import re
text = '我的电话号码是09954323178,他的电话号码是0995开头的对吗'
data_list = re.findall("95(4\d{5}|\w+)",text)
print(data_list) # ['432317', '开头的对吗']
# 外面套一个括号的话,就是在上面返回的基础上多返回东西
text = '我的电话号码是09954323178,他的电话号码是0995开头的对吗'
data_list = re.findall("(95(4\d{5}|\w+))",text)
print(data_list) # [('95432317', '432317'), ('95开头的对吗', '开头的对吗')]
4. 起始和结束
上述示例重都是从一段文本中提取数据,只要文本中存在就可以
但是如果要求用户输入的内容必须是指定的内容开头和结尾,比如用户输入的邮箱是否符合规范(也就是起到校验作用),就需要用到下面两个字符。
^开始$结束
import re
text = t75xxxxx@qq.com
email_list = re.findall("^\w+@\w+\.\w+$")
5. 特殊字符
正则表达式中[ . \ / { } ( )都有特殊的含义,因此如果在匹配的时候需要匹配这些特殊字符,则需要进行转义操作
import re
text = "早上1{5}好"
data = re.findall("\d\{5\}",text)
print(data) # ['1{5}']
6. Python re模块
findall获得匹配到的所有数据
import re
text = 'abc111111198002292222++2222221000122199999'
data_list = re.findall("\d{6}(\d{4})(\d{2})(\d{2})\d{3}[\dX]", text)
# 只给年月日分组
print(data_list) # [('1980', '02', '29'), ('1000', '12', '21')]
match从起始位置匹配,匹配成功返回第一个对象,没成功返回None
import re
text = '我永远爱2B小姐姐'
result = re.match('爱\d\w+', text)
# 因为必须从起始位置匹配,类似于咱们在4中开始和结束中用到的^和$,开头必须得是 爱开头才行
print(result) # None
text = '爱2B小姐姐 123'
result = re.match('爱\d\w+', text)
# 这个result是个特殊的对象
print(result) # <re.Match object; span=(0, 6), match='爱2B小姐姐'>
if result:
print(result.group()) # 爱2B小姐姐
search,浏览整个字符串去匹配第一个,未匹配成功返回None
import re
text = '爱2B小姐姐她爱3B小姐姐'
result = re.search('爱\d\w', text)
# 这个result也是个特殊的对象
print(result) # <re.Match object; span=(0, 3), match='爱2B'>
if result:
print(result.group()) # 爱2B
sub,替换匹配成功的字符串
import re
text = '我爱2B小姐姐她爱3B小姐姐'
result = re.sub('爱\d\w', 'DD',text)
print(result) # 我DD小姐姐她DD小姐姐
# 从左到右把前几个给替换了
result = re.sub('爱\d\w', 'DD',text, 1)
print(result) # 我DD小姐姐她爱3B小姐姐
split,根据匹配成功的位置分割
import re
text = '我爱2B小姐姐她爱3B小姐姐'
result = re.split('爱\d\w',text)
print(result) # ['我', '小姐姐她', '小姐姐']
finditer,和findall一样,但是返回一个迭代器,这样节省一些空间
import re
text = ""
for i in range(10000):
text += f'爱{i}B小姐姐。'
print(text)
result = re.finditer('爱\d+B', text)
for item in result:
print(item.group()) # ['我', '小姐姐她', '小姐姐']
补充:可以获得字典形式的结果
import re
text = 'abc111111198002292222++2222221000122199999'
data_list = re.finditer("\d{6}(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})\d{3}[\dX]", text)
for item in data_list:
print(item.groupdict()) # {'year': '1980', 'month': '02', 'day': '29'}
{'year': '1000', 'month': '12', 'day': '21'}
本文通过观看《70分钟搞定正则表达式》视频教程,讲解了正则表达式的字符匹配、数量控制、分组、边界标志和特殊字符的使用,并展示了Python re模块的实战应用,如查找文本、匹配邮箱地址等。
614

被折叠的 条评论
为什么被折叠?



