Python正则表达式知识点串联

本文通过观看《70分钟搞定正则表达式》视频教程,讲解了正则表达式的字符匹配、数量控制、分组、边界标志和特殊字符的使用,并展示了Python re模块的实战应用,如查找文本、匹配邮箱地址等。

本文为观看武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'}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值