Python-24-正则表达式

本文深入介绍了Python中的正则表达式,包括基本概念、re模块的使用、匹配单个字符、匹配多个字符、匹配开头和结尾、匹配分组、贪婪匹配以及其他实用方法。通过实例演示了正则表达式的功能,如验证用户输入、爬虫数据提取等,强调了其在编程中的广泛应用和重要性。
摘要由CSDN通过智能技术生成

正则表达式

一、概述

  • 概念

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

再比如:需要爬取页面中内容,邮箱(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 re

rst = 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())                # 123456


r = re.match(r'\d{6}', '123')
print(r.group())                # 匹配失败
  • {m,n}
r = re.match(r'\d{2,5}', '123456789')
print(r.group())                # 12345

r = 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<name>)分组起别名
(?P=name)引用别名为name分组匹配到的字符串
  • |()
''' 需求
匹配163、qq、gmail邮箱地址,邮箱用户名为6-10位
正则表达式为:[A-Za-z0-9_]{6,10}@(163|qq|gmail)\.com$
'''

import re

lst = ['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 re

str1 = '<body><h1>我是一级标题</h1></body>'

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

str1 = '<body><h1>我是一级标题</h1></body>'

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

七、贪婪匹配

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

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

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

import re

str3 = "woniuxywoniuxywoniuxy"
res1 = re.match("w.*y", str3)       # 贪婪匹配
print(res1.group())			# woniuxywoniuxywoniuxy

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

八、其它使用方法

  • search:从字符串内开始匹配
'''
匹配出Python = 996里的数字
'''

import re

rst = re.search(r'\d+', 'Python = 996')
print(rst.group())

''' 结果
996
'''
  • findall:匹配字符串中的所有满足规则的字符串,并将匹配结果以列表形式返回
import re

rst = re.findall(r'\d+', 'Python=996,java=007,C++=955')
print(rst)

''' 结果
['996', '007', '955']
'''
  • sub:替换
  1. 使用字符串进行替换
import re

rst = re.sub(r'\d+', '123', 'Python=996,java=107,C++=955')
print(rst)

''' 结果
Python=123,java=123,C++=123
'''
  1. 使用函数进行替换
import re

def add_sub(tmp):
    n = int(tmp.group())
    n += 1
    return 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']
'''

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值