Python-24-正则表达式

正则表达式

一、概述

  • 概念

比如说:在实际开发中,可以需要验证注册用户的名称是否满足某种(使用字母和下划线),程序员需要对每个用户输入的内容进行规则的对比;

再比如:需要爬取页面中内容,邮箱(xxx@域名)、手机号、图片的链接;

正则表达式就是满足某种规则的一段代码。英文名称:Regular Expression,简称RE

  • 特点
    • 语法比较诡异,可读性很差
    • 通用性很强,绝大多数的编程语法都正则表达式。

二、re模块

# 导入re模块
import re# 使用match函数进行匹配,match默认从开头开始匹配
r = re.match(r'测试', '测试开发57')# 打印匹配结果
print(r.group())		# 测试

三、匹配单个字符

代码功能
.匹配任意一个字符,不能匹配\n
[]匹配[]中列举的字符
\d匹配数字,即0-9
\D匹配非数字,即不是数字
\s匹配空白,即\n\t
\S匹配非空白字符
\w匹配非特殊字符,即a-z、A-Z、0-9、下划线、汉字
\W匹配特殊字符,即非数字、非字母、非汉字
  • \d\D
# \d
r = re.match(r'测试开发\d', '测试开发57')
print(r.group())r = re.match(r'测试开发\d', '测试开发A')
print(r.group())            # 匹配失败# \D
r = re.match(r'测试开发\D', '测试开发A')
print(r.group())                    # 匹配成功r = re.match(r'测试开发\D', '测试开发!')
print(r.group())                    # 匹配成功
  • \w\W
# \w
r = re.match(r'测试开发\w', '测试开发A')
print(r.group())					# 匹配成功r = re.match(r'测试开发\w', '测试开发班')
print(r.group())					# 匹配成功# \W
r = re.match(r'测试开发\W', '测试开发A')
print(r.group())					# 匹配失败r = re.match(r'测试开发\W', '测试开发\n')
print(r.group())					# 匹配成功r = re.match(r'测试\W开发', '测试 开发')
print(r.group())					# 匹配成功
  • \s\S
# \s
r = re.match(r'测试开发\s', '测试开发\n')
print(r.group())					# 匹配成功r = re.match(r'测试\s开发', '测试\t开发')
print(r.group())					# 匹配成功# \S
r = re.match(r'测试\S开发', '测试#开发')
print(r.group())					# 匹配成功
  • []
lst = ['测试开发a', '测试开发e', '测试开发A', '测试开发R', '测试开发5', '测试开发_']
for i in lst:r = re.match(r'测试开发[0-9A-Za-z_]', i)		# 匹配所有的字母和数字if r:print(r.group())else:print(f'{i}----匹配失败')

扩展:[^]:表示对[]中的内容取反。

# lst = ['测试开发a', '测试开发e', '测试开发A', '测试开发R', '测试开发5', '测试开发^']
for i in lst:r = re.match(r'测试开发[^0-9^a-z]', i)if r:print(r.group())else:print(f'{i}----匹配失败')""" 结果:
测试开发a----匹配失败
测试开发e----匹配失败
测试开发A
测试开发R
测试开发5----匹配失败
测试开发^----匹配失败
"""
  • .
import rerst = re.match(r'测试开发.', '测试开发3')
print(rst.group())			# 测试开发3# 使用 .* 匹配多行文本
str1 = """asdf
aaaaaaaaasdfasdf
asdfa
adfadsfsa
asdfasdf
asdfasdf"""rst = re.match(r'.*', str1)     # * 是匹配前一个字符出0次或无数次
print(rst.group())''' 结果:. 不能匹配 \n
asdf
'''# 如何使用 . 匹配\n,那么在match等方法中加入一个参数 re.S
rst = re.match(r'.*', str1, re.S)     # * 是匹配前一个字符出0次或无数次
print(rst.group())''' 结果
asdfaaaaaaaaasdfasdf
asdfa
adfadsfsa
asdfasdf
asdfasdf
'''

四、匹配多个字符

代码功能
*匹配前一个字符出现0次或者无数次,即可有可无
+匹配前一个字符出现1次或者无数次,即至少一次
?匹配前一个字符出现0次或者1次
{m}匹配前一个字符出现m次
{m,n}匹配前一个字符出现m到n次
  • *
r = re.match(r'\d*', '0123A456789')
print(r.group())r = re.match(r'测试.*', '测试开发57')
print(repr(r.group()))            # '测试开发57'
  • +
r = re.match(r'\d+', '0123456789')
print(r.group())r = re.match(r'\w+', '中国')
print(r.group())r = re.match(r'\w+', '')
print(r.group())            # 报错。匹配失败
  • ?
r = re.match(r'\d?', 'A567')
print(r.group())            # 匹配成功r = re.match(r'\d?', '')
print(r.group())            # 匹配成功
  • {n}
r = re.match(r'\d{6}', '123456789')
print(r.group())                # 123456r = re.match(r'\d{6}', '123')
print(r.group())                # 匹配失败
  • {m,n}
r = re.match(r'\d{2,5}', '123456789')
print(r.group())                # 12345r = re.match(r'\d{2,5}', '1')
print(r.group())
  • 练习:匹配座机号码
number_list = ['023-68237890', '010-68923098', '0913-68681987', '02389891235', '091398783620']for i in number_list:r = re.match(r'0\d{2,3}-?\d{8}', i)if r:print(r.group())else:print(f'{i}---匹配失败!')

五、匹配开头和结尾

代码功能
^匹配字符串开头
$匹配字符串结尾
  • ^
"""
需求:匹配以一个数字开头,数字之后跟上python的字符
search():表示任意位置进行匹配
"""lst1 = ['3python', '8ipython', 'python9', '_python', 'A6python','9python123']for i in lst1:r = re.search(r'^\dpython', i)if r:print(r.group())else:print(f'{i}---匹配失败..')
  • $
# 匹配以数字开头,并且以数字结尾,中间字符任意lst1 = ['3python', '8ipython', 'python9', '_python2', 'A6python6','9python123', '3', '12']for i in lst1:r = re.search(r'^\d.*\d$', i)if r:print(r.group())else:print(f'{i}---匹配失败..')
  • ^$:匹配空串
r = re.search(r'^$', '')
print(repr(r.group()))

六、匹配分组

代码功能
|匹配左右任意一个表达式
()将括号中字符作为一个分组
\number引用分组number匹配
(?P)分组起别名
(?P=name)引用别名为name分组匹配到的字符串
  • |()
''' 需求
匹配163、qq、gmail邮箱地址,邮箱用户名为6-10位
正则表达式为:[A-Za-z0-9_]{6,10}@(163|qq|gmail)\.com$
'''import relst = ['liupan@163.com', 'liupan@qq.com', 'liupan@gmail']for i in lst:rst1 = re.match(r'[A-Za-z0-9_]{6,10}@(163|qq|gmail)\.com$', 'liupan@163.com')if rst1:print(rst1.group())else:print(f'{i}---匹配失败')

注意:邮箱中的.需要进行转义处理,不然在正则表达式中会当做元字符.匹配任意单个字符!

  • \number:后项引用前项
import restr1 = '

我是一级标题

'
rst1 = re.match(r'<(\w+)><(\w+)>.*', str1) print(rst1.group())
  • (?P)(?P=name)
import restr1 = '

我是一级标题

'
rst1 = re.match(r'<(?P\w+)><(?P\w+)>.*', str1) print(rst1.group())

七、贪婪匹配

贪婪和非贪婪:*+{} 后面加上?就是非贪婪。

贪婪匹配:尽可能多地匹配

非贪婪相反,表示尽可能少地匹配

import restr3 = "woniuxywoniuxywoniuxy"
res1 = re.match("w.*y", str3)       # 贪婪匹配
print(res1.group())			# woniuxywoniuxywoniuxyres2 = re.match("w.*?y", str3)      # 非贪婪匹配
print(res2.group())			# woniuxy

八、其它使用方法

  • search:从字符串内开始匹配
'''
匹配出Python = 996里的数字
'''import rerst = re.search(r'\d+', 'Python = 996')
print(rst.group())''' 结果
996
'''
  • findall:匹配字符串中的所有满足规则的字符串,并将匹配结果以列表形式返回
import rerst = re.findall(r'\d+', 'Python=996,java=007,C++=955')
print(rst)''' 结果
['996', '007', '955']
'''
  • sub:替换
  1. 使用字符串进行替换
import rerst = re.sub(r'\d+', '123', 'Python=996,java=107,C++=955')
print(rst)''' 结果
Python=123,java=123,C++=123
'''
  1. 使用函数进行替换
import redef add_sub(tmp):n = int(tmp.group())n += 1return str(n)rst = re.sub(r'\d+', add_sub, 'Python=996,java=107,C++=955')
print(rst)''' 结果
Python=997,java=108,C++=956
'''
  • split:切割
str1 = 'info:python 996 java 007'rst = re.split(r':| ', str1)		# 不要使用()分组
print(rst)''' 结果
['info', 'python', '996', 'java', '007']
'''

通过正则表达式进行切割,使用分组时注意,分组也会作为切割后的列表元素。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部