Python-正则表达式(re 模块)

目录

  • 一、re 模块的使用过程
  • 二、正则表达式的字符匹配
    • 1. 匹配开头结尾
    • 2. 匹配单个字符
    • 3. 匹配多个字符
    • 4. 匹配分组
    • 5. Python 代码示例
  • 三、re 模块的函数
    • 1. 函数一览表
    • 2. Python 代码示例
      • 1)search 与 finditer
      • 2)findall
      • 3)sub
      • 4)split
  • 四、贪婪与非贪婪
  • 五、re 模块的可选标志


参考文章:
【re — 正则表达式操作】
【正则表达式指南】
【Python 正则表达式 | 菜鸟教程】
【Python 正则表达式 | 极客教程】
【Python正则表达式详解 (超详细,看完必会!)】

一、re 模块的使用过程

# 导入 re 模块
import re# 使用 match 方法进行匹配操作
# re.match() 能够匹配出以 xxx 开头的字符串
result = re.match(r'正则表达式', '被匹配的字符串')if result:# 如果上一步匹配到数据的话,可以使用 group 方法来提取数据print(result.group())
else:print('匹配失败')

需要注意的是:

Python 中字符串前面加上 r 表示原生字符串。与大多数编程语言相同,正则表达式里使用 “\” 作为转义字符,这就可能造成反斜杠困扰。Python 里的原生字符串很好地解决了这个问题,同时写出来的表达式也更直观。注意 r 只服务于 “\” ,不对其他进行转义。

二、正则表达式的字符匹配

1. 匹配开头结尾

字符介绍
^匹配字符串的开头
$匹配字符串的末尾

2. 匹配单个字符

字符介绍
.匹配任意一个字符,除了换行符 \n
[]匹配一个 [ ] 中列举的字符
[^]匹配除 [ ] 中列举的字符外的字符
\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匹配空字符串,但只在单词开始或结尾的位置
\B匹配空字符串,但仅限于它不在单词的开头或结尾的情况
\A匹配字符串开始
\Z匹配字符串结尾
  • \ 是转义特殊字符,\n 代表换行、\r 代表回车、\f 代表换页、\t 代表 Tab 键

  • 通过用 ‘-’ 将两个字符连起来可以表示字符范围,比如:

    • [a-z] 将匹配任何小写 ASCII 字符, [0-5][0-9] 将匹配从 00 到 59 的两位数字,[0-9A-Fa-f] 将匹配任何十六进制数位。
    • 如果 - 进行了转义 (比如 [a\-z])或者它的位置在首位或末尾(如 [-a] 或 [a-]),那么它就只表示普通字符 ‘-’
  • 除反斜杠外的特殊字符在 [ ] 中会失去其特殊含义,例如:[(+*)] 将匹配字符为 ( + * 或 ) 中的任何一个

3. 匹配多个字符

字符介绍
*匹配前一个字符出现 0 次或者无限次
+匹配前一个字符出现 1 次或者无限次
?匹配前一个字符出现 1 次或者 0 次
{m}匹配前一个字符出现 m 次
{m,n}匹配前一个字符出现从 m 至 n 次
{m,}匹配前一个字符出现至少 m 次
  • ab* 会匹配 ‘a’,‘ab’,或者 ‘a’ 后面跟随任意个 ‘b’

  • ab+ 会匹配 ‘a’ 后面跟随 1 个以上到任意个 ‘b’,它不会匹配 ‘a’

  • ab? 会匹配 ‘a’ 或者 ‘ab’

  • a{6} 将匹配 6 个 ‘a’ , 少于 6 个的话就会导致匹配失败

  • a{3,5} 将匹配 3 到 5 个 ‘a’

4. 匹配分组

字符介绍
|如果 A 和 B 是正则表达式,A|B 将匹配任何与 A 或 B 匹配的字符串
()将括号中的字符作为一个分组
\num引用分组 num 匹配到的字符串
(?P<name>)分组所匹配到了的字符串可通过符号分组名称 name 来访问
(?P=name)匹配前面叫 name 的命名组中所匹配到的串

5. Python 代码示例

  • 匹配出 126、163、qq 的邮箱地址,且 @ 符号之前有 4 到 20 位数字、大写或小写字母和下划线的组合。
import reemail_list = ["Alice27@163.com", "Sam_1122@gmail.com", ".Tom_12@qq.com", "Bob_1988@qq.com.com", "Elowen@126.com", "Ice@qq.com", "nicetomeetyou@qq.com"]for email in email_list:ret = re.match(r"\w{4,20}@(163|126|qq)\.com$", email)if ret:print("%s 是符合规定的邮件地址 , 匹配后的结果是 : %s" % (email, ret.group()))else:print("%s 不符合要求" % email)

结果展示:

Alice27@163.com 是符合规定的邮件地址 , 匹配后的结果是 : Alice27@163.com
Sam_1122@gmail.com 不符合要求
.Tom_12@qq.com 不符合要求
Bob_1988@qq.com.com 不符合要求
Elowen@126.com 是符合规定的邮件地址 , 匹配后的结果是 : Elowen@126.com
Ice@qq.com 不符合要求
nicetomeetyou@qq.com 是符合规定的邮件地址 , 匹配后的结果是 : nicetomeetyou@qq.com
  • 匹配 11 位不是以 4、7 结尾的手机号码:re.match(r"1\d{9}[0-35-68-9]$", tel)

  • 提取区号和电话号码:ret = re.match(r"([^-]+)-(\d+)","010-12345678") ,此时 ret.group(1) = ‘010’ ,ret.group(2) = ‘12345678’ ,ret.group(0) 等价于 ret.group() 等于 ‘010-12345678’

  • 匹配标签,例如:匹配 <html><h1>hello</h1></html> 并提取出 hello

import retexts = ['<html><h1>hello</h1></html>', '<html><h1>world</h1></html1html>','<html><h1>hello</h2></html>']def match():for text in texts:ret = re.match(r'<([a-zA-Z]*)><([a-zA-Z0-9]*)>(\w*)</\2></\1>', text)if ret:print(f'匹配成功,标签为 {ret.group()},信息为 {ret.group(3)}')else:print(f'{text} 标签匹配失败')if __name__ == '__main__':match()

结果展示:

匹配成功,标签为 <html><h1>hello</h1></html>,信息为 hello
<html><h1>world</h1></html1html> 标签匹配失败
<html><h1>hello</h2></html> 标签匹配失败
  • 用 (?P<name>) 和 (?P=name) 改进上述示例:
    re.match(r'<(?P<name1>[a-zA-Z]*)><(?P<name2>[a-zA-Z0-9]*)>(\w*)</(?P=name2)></(?P=name1)>', text)
    注意:字母 P 要大写

三、re 模块的函数

1. 函数一览表

函数含义
re.compile(pattern, flags=0)将正则表达式的样式编译为一个正则表达式对象(正则对象),可以用于匹配
re.search(pattern, string, flags=0)扫描整个字符串,返回第一个匹配项
re.match(pattern, string, flags=0)从字符串开始位置匹配正则表达式
re.fullmatch(pattern, string, flags=0)如果整个 string 与正则表达式 pattern 匹配,则返回相应的 Match
re.split(pattern, string, maxsplit=0, flags=0)按匹配项分割字符串
re.findall(pattern, string, flags=0)返回字符串中所有匹配的子串
re.finditer(pattern, string, flags=0)针对正则表达式 pattern 在 string 里的所有非重叠匹配返回一个产生 Match 对象的迭代器
re.sub(pattern, repl, string, count=0, flags=0)替换字符串中所有匹配正则表达式的部分
re.subn(pattern, repl, string, count=0, flags=0)行为与 sub() 相同,但是返回一个元组,包含 (替换后的字符串, 替换次数)
re.escape(pattern)转义 pattern 中的特殊字符,结果可直接用作匹配字符串
re.purge()清除正则表达式的缓存
  • result = re.match(pattern, string) 等价于 prog = re.compile(pattern)result = prog.match(string)

  • re.split 函数中如果 maxsplit 非零,则最多进行 maxsplit 次分隔,剩下的字符全部返回到列表的最后一个元素。

2. Python 代码示例

1)search 与 finditer

需求:匹配出文章阅读的次数和点赞的次数。

import redef find_second_match(pattern, text):matches = re.finditer(pattern, text)try:next(matches)  # 跳过第一个匹配项second_match = next(matches)  # 获取第二个匹配项return second_match.group()except StopIteration:return Noneif __name__ == '__main__':p = r"\d+"t = "阅读次数为 9999 , 点赞次数为 19999"ret = re.search(p, t)print(f'阅读次数为 {ret.group()} , 点赞次数为 {find_second_match(p, t)}')

结果展示:

阅读次数为 9999 , 点赞次数为 19999

2)findall

  • 需求:统计出相应文章阅读、点赞和收藏的次数。
import reret = re.findall(r"\d+", "read = 9999, thumbs up = 7890, collection = 12345")
print(f'阅读次数 {ret[0]} ,点赞次数 {ret[1]} ,收藏次数 {ret[2]}')

结果展示:

阅读次数 9999 ,点赞次数 7890 ,收藏次数 12345

【拓展】:分组() 内加入 ?: 可以避免只返回分组内的内容。

  • 需求:提取出字符串里的日期和时间 。
import reif __name__ == '__main__':s = 'hello world, now is 2020/7/20 18:48, 现在是 2020年7月20日18时48分。'ret_s = re.sub(r'年|月', r'/', s)ret_s = re.sub(r'日|分', r' ', ret_s)ret_s = re.sub(r'时', r':', ret_s)# hello world, now is 2020/7/20 18:48, 现在是 2020/7/20 18:48 。print(ret_s)# findallcom1 = re.compile(r'\d{4}/[01]?[0-9]/[1-3]?[0-9]\s(0[0-9]|1[0-9]|2[0-4])\:[0-5][0-9]')ret1 = com1.findall(ret_s)print(ret1[0])  # 18# 加 ?:com2 = re.compile(r'\d{4}/[01]?[0-9]/[1-3]?[0-9]\s(?:0[0-9]|1[0-9]|2[0-4])\:[0-5][0-9]')ret2 = com2.findall(ret_s)print(ret2[0])  # 2020/7/20 18:48# searchret3 = re.search(r'\d{4}/[01]?[0-9]/[1-3]?[0-9]\s(0[0-9]|1[0-9]|2[0-4])\:[0-5][0-9]', ret_s)print(ret3.group())  # 2020/7/20 18:48

3)sub

将匹配到的数据进行替换。

  • 需求:将匹配到的阅读次数加 1 。
import redef add(temp):str_num = temp.group()num = int(str_num) + 1return str(num)if __name__ == '__main__':ret = re.sub(r"\d+", '998', "thumbs up = 997")print(ret)ret = re.sub(r"\d+", add, "thumbs up = 997")print(ret)ret = re.sub(r"\d+", lambda x: str(int(x.group()) + 1), "thumbs up = 997")print(ret)print('-' * 30)# count 替换次数text = "apple apple apple apple"pattern = r"apple"replacement = "orange"new_text = re.sub(pattern, replacement, text, count=2)print(new_text)

结果展示:

thumbs up = 998
thumbs up = 998
thumbs up = 998
------------------------------
orange orange apple apple
  • 需求:删除字符串中所有的 HTML 标签和 &nbsp; 实体,只留下纯文本内容。
import reif __name__ == '__main__':text = ('<div>' + '\n' +'<p>岗位职责:</p>' + '\n' +'<p>完成推荐算法、数据统计、接口、后台等服务器端相关工作</p>' + '\n' +'<p><br></p>' + '\n' +'<p>必备要求:</p>' + '\n' +'<p>良好的自我驱动力和职业素养,工作积极主动、结果导向</p>' + '\n' +'<p>&nbsp;<br></p>' + '\n' +'<p>技术要求:</p>' + '\n' +'<p>1、一年以上 Python 开发经验,掌握面向对象分析和设计,了解设计模式</p>' + '\n' +'<p>2、掌握 HTTP 协议,熟悉 MVC、MVVM 等概念以及相关 WEB 开发框架</p>' + '\n' +'<p>3、掌握关系数据库开发设计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种<br></p>' + '\n' +'<p>4、掌握 NoSQL、MQ,熟练使用对应技术解决方案</p>' + '\n' +'<p>5、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js</p>' + '\n' +'<p>&nbsp;<br></p>' + '\n' +'<p>加分项:</p>' + '\n' +'<p>大数据,数理统计,机器学习,sklearn,高性能,大并发。</p>' + '\n' +'</div>')# print(text)sub_result = re.sub(r"<[^>]*>|&nbsp;", "", text)print(sub_result)

结果展示:

岗位职责:
完成推荐算法、数据统计、接口、后台等服务器端相关工作必备要求:
良好的自我驱动力和职业素养,工作积极主动、结果导向技术要求:
1、一年以上 Python 开发经验,掌握面向对象分析和设计,了解设计模式
2、掌握 HTTP 协议,熟悉 MVC、MVVM 等概念以及相关 WEB 开发框架
3、掌握关系数据库开发设计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种
4、掌握 NoSQL、MQ,熟练使用对应技术解决方案
5、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js加分项:
大数据,数理统计,机器学习,sklearn,高性能,大并发。

解析正则表达式:r"<[^>]*>|&nbsp;"

  1. <[^>]*> :匹配一对尖括号 < > 及其内部内容,且内容不包含 > 符号,表示匹配 HTML 标签,比如 <div>, <a href=“…”> 等。

  2. | :表示 “或” 操作符。

  3. &nbsp; :匹配 HTML 的不间断空格实体 &nbsp;

  4. 替换字符串是 “” ,即将匹配的内容替换为空字符串(删除)。

4)split

根据匹配进行切割字符串,并返回一个列表。需求:切割字符串 “info:xiaoZhang 33 shandong” 。

import reret = re.split(r":| ","info:xiaoZhang 33 shandong")
print(ret)

结果展示:

['info', 'xiaoZhang', '33', 'shandong']

四、贪婪与非贪婪

Python 里数量词默认是贪婪的,即总是尝试匹配尽可能多的字符,而非贪婪则相反,总是尝试匹配尽可能少的字符。

可以在 * , ? , + , {m,n} 后面加上非贪婪操作符 ? ,该操作符要求正则匹配的字符越少越好,因而可以将贪婪转变为非贪婪。

Python 代码示例:

import reif __name__ == '__main__':s = "This is a number 234-235-22-423"# 贪婪print(re.match(r".+(\d+-\d+-\d+-\d+)", s).group(1))print(re.match(r"aa(\d+)", "aa2343ddd").group(1))print(re.match(r"aa(\d+)ddd", "aa2343ddd").group(1))print('-' * 30)# 非贪婪print(re.match(r".+?(\d+-\d+-\d+-\d+)", s).group(1))print(re.match(r"aa(\d+?)", "aa2343ddd").group(1))print(re.match(r"aa(\d+?)ddd", "aa2343ddd").group(1))

结果展示:

4-235-22-423
2343
2343
------------------------------
234-235-22-423
2
2343

五、re 模块的可选标志

标志介绍
re.I使匹配对大小写不敏感
re.A不让 \w 匹配汉字
re.L做本地化识别(locale-aware)匹配
re.M多行匹配,影响 ^ 和 $
re.S使 . 匹配包括换行符 \n 在内的所有字符
re.U根据 Unicode 字符集解析字符,这个标志影响 \w \W \b \B
re.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解

Python 代码示例:

import reif __name__ == '__main__':s1 = 'hello\nworld'ret1 = re.match(r'hello.W', s1, re.S | re.I)if ret1:print(ret1.group())  # hello welse:print('no match')print('-' * 15)s2 = 'hello你好world'ret2 = re.match(r'hello\w*', s2, re.A)if ret2:print(ret2.group())  # helloelse:print('no match')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/83051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端知识导图

前端知识导图 参考&#xff1a;字节标准 前端知识导图 通用基础 1、编程语言 HTML CSS JS TS 2、计算机基础 计算机网略 数据结构 算法&#xff1a;二分查找、十大排序、二叉树先中后和层次遍历、集合交并集、leetcode刷题经验 编译构建 webpack & vite 应用基础 开…

moon游戏服务器-demo运行

下载地址 https://github.com/sniper00/MoonDemo redis安装 Redis-x64-3.0.504.msi 服务器配置文件 D:\gitee\moon_server_demo\serverconf.lua 貌似不修改也可以的&#xff0c;redis不要设置密码 windows编译 安装VS2022 Community 下载premake5.exe放MoonDemo\server\moon 双…

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…

ajax学习手册

Ajax 通俗易懂学习手册 目录 Ajax 基础概念XMLHttpRequest 详解Fetch API (现代方式)处理不同数据格式错误处理和状态码Ajax 高级技巧实战项目案例最佳实践 Ajax 基础概念 什么是 Ajax&#xff1f; Ajax Asynchronous JavaScript And XML 通俗解释&#xff1a; Ajax 就像…

人工智能学习02-安装环境

人工智能学习概述—快手视频 人工智能学习02-安装—快手视频 Python安装 Python安装分为两种方法&#xff0c;一是从官网(https://www.python.org/)下载Python工具(比如python-2.7.msi)进行安装&#xff0c;并设置Path环境变量&#xff1b;二是下载工具Anaconda集成环境进行安…

电脑开不了机,主板显示67码解决过程

文章目录 现象分析内存条问题BIOS设置问题其它问题 解决清理内存条金手指所需工具操作步骤注意事项 电脑在运行过程中&#xff0c;显示内存不足&#xff0c;重启电脑却无法启动。 现象 System Initialization 主板风扇是转的&#xff0c;也有灯光显示&#xff0c;插上屏幕&am…

在ubuntu等linux系统上申请https证书

使用 Certbot 自动申请 安装 Certbot Certbot 是 Let’s Encrypt 官方推荐的自动化工具&#xff0c;支持多种操作系统和服务器环境。 在 Ubuntu/Debian 上&#xff1a; sudo apt update sudo apt install certbot申请证书 纯手动方式&#xff08;不自动配置&#xff09;&…

springboot的test模块使用Autowired注入失败

springboot的test模块使用Autowired注入失败的原因&#xff1a; 注入失败的原因可能是用了junit4的包的Test注解 import org.junit.Test;解决方法&#xff1a;再加上RunWith(SpringRunner.class)注解即可 或者把Test由junit4改成junit5的注解&#xff0c;就不用加上RunWith&…

Cursor Rules 使用

前言 最近在使用 Cursor 进行编程辅助时&#xff0c;发现 AI 生成的代码风格和当前的代码风格大相径庭。而且有时它会输出很奇怪的代码&#xff0c;总是不符合预期。 遂引出本篇&#xff0c;介绍一下 Rules &#xff0c;它就可以做一些规范约束之类的事情。 什么是 Cursor R…

项目任务,修改svip用户的存储空间。

修改存储空间 3GB->5GB&#xff0c;这是项目任务&#xff0c;首先有人任务就要去思考实现思路&#xff0c;首先存储空间&#xff0c;也就是说不只是前端样式3GB改一下就可以了&#xff0c;那用户实际还是3GB&#xff0c;所以我们去网站看后端谁返回给我们了3GB&#xff0c;我…

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…

iview中的table组件点击一行中的任意一点选中本行

<Table border ref"selection" size"small" on-row-click"onClickRow"></Table>// table组件点击一行任意位置选中onClickRow(row, index) {this.$refs.selection.toggleSelect(index)}写上toggleSelect(index)方法即可&#xff0c;…

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…

算法-构造题

#include<iostream> #include<bits/stdc.h> using namespace std; typedef long long ll; const ll N 5e5 10; int main() {ll n, k;cin >> n >> k; ll a[N] {0}; // 初始化一个大小为N的数组a&#xff0c;用于存储排列// 构造满足条件的排列for (l…

LeetCode--25.k个一组翻转链表

解题思路&#xff1a; 1.获取信息&#xff1a; &#xff08;1&#xff09;给定一个链表&#xff0c;每k个结点一组进行翻转 &#xff08;2&#xff09;余下不足k个结点&#xff0c;则不进行交换 2.分析题目&#xff1a; 其实就是24题的变题&#xff0c;24题是两两一组进行交换&…

OC—UI学习-2

导航控制器和导航工具栏 导航控制器 UINAvigationController与UIViewController的关系 UIViewController是什么&#xff1f; 它是一个普通的视图控制器&#xff0c;负责管理一个页面 UINavigationController是什么&#xff1f; 它是一个容器控制器&#xff0c;专门用来管理一…

Microsoft前后端不分离编程新风向:cshtml

文章目录 什么是CSHTML&#xff1f;基础语法内联表达式代码块控制结构 布局页面_ViewStart.cshtml_Layout.cshtml使用布局 模型绑定强类型视图模型集合 HTML辅助方法基本表单验证 局部视图创建局部视图使用局部视图 高级特性视图组件依赖注入Tag Helpers 性能优化缓存捆绑和压缩…

【SpringBoot+SpringCloud】Linux配置nacos踩坑大全

*建议在开发时使用Linux环境下搭建nacos 1.在nacos官网找到搭配SpringBoot和SpringCloud的版本 2.Nacos 依赖 Java 环境来运行&#xff0c;需要在linux系统中安装JDK 1.8 3.按照Nacos官网步骤安装&#xff0c;防火墙配置开放8848和9848端口 客户端拥有相同的计算逻辑&…

如何在 Java 中优雅地使用 Redisson 实现分布式锁

分布式系统中&#xff0c;节点并发访问共享资源可能导致数据一致性问题。分布式锁是常见的解决方案&#xff0c;可确保操作原子性。Redisson是基于Redis的Java分布式对象库&#xff0c;提供多种分布式同步工具&#xff0c;包括分布式锁。Redisson与Redis&#xff08;实时数据平…

pikachu靶场通关笔记20 SQL注入03-搜索型注入(GET)

目录 一、SQL注入 二、搜索型注入 三、源码分析 1、渗透思路1 2、渗透思路2 四、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入百分号单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取…