python自学之《21天学通Python》(10)——正则表达式

news2024/7/6 21:10:49

第13章 正则表达式

最初的正则表达式出现于理论计算机科学的自动控制理论和形式化语言理论中。在这些领域中有对计算(自动控制)的模型和对形式化语言描述与分类的研究。

程序员所用的正则表达式是指用某种模式去匹配一类具有共同特征的字符串。正则表达式主要用于处理文本,正则表达式能够使文本处理简单起来,尤其对于复杂的查找替换这样的工作,使用正则表达式会非常快的完成。流行的文本编辑器(如Emacs、Vim等)大都支持正则表达式。

13.1 正则表达式基础

维基百科所言:正则表达式又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或re),是计算机科学的一个概念。本节详细介绍了正则的概念和应用。

13.1.1 正则表达式概述

正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由UNIX中的工具软件(例如sed和grep)普及开的。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。

正则表达式主要用于快速地搜索、替换或验证具有特殊形式或格式的文本,可以应用于文本编辑、查找,也可以应用于web数据处理与分析等领域。

13.1.2 正则表达式基本元字符

元字符是正则表达式中具有特定含义的字符,在正则表达式中可以在字符串中使用元字符来匹配字符串的各种可能的情况。常用的元字符如表13.1所示。

![在这里插入图片描述](https://img-blog.csdnimg.cn/46ada904d706494ba53253042420b65f.png#pic_center)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

>>> import re
>>> re.compile('\\ba.?')
re.compile('\\ba.?')
>>> re.compile(r'\ba.?')
re.compile('\\ba.?')
>>> re.compile('\\\\word')
re.compile('\\\\word')
>>> re.compile(r'\\word')
re.compile('\\\\word')
>>> 

注意 正则表达式的元字符有很多,只有经常用它,才能熟练识记。

13.1.3 常用正则表达式
在这里插入图片描述

注意以上只是处理以13开头的手机号码,随着手机号码的不断推出,现在还有14、15、不18开头的手机号。这里为了简化正则表达式,使初学者能看懂,暂不处理其他号段的情况。

在这里插入图片描述
在这里插入图片描述
13.2 re模块

re模块是Python语言提供的处理正则表达式的标准库,在该模块中,既可以直接匹配正则表达式的基本函数,也可以通过编译正则表达式对象,并使用其方法来使用正则表达式。

13.2.1 正则匹配搜索函数
在这里插入图片描述
在这里插入图片描述
注意 区分match()函数和search()函数的功能,一个只能从第一个字符开始匹配,一个可以从要匹配的字符串的中间任一个字符进行匹配。
在这里插入图片描述
在这里插入图片描述

>>> import re
>>> s = 'Life can be good'
>>> print(re.match ('can',s))
None
>>> print(re.search('can',s))
<re.Match object; span=(5, 8), match='can'>
>>> print(re.match('1.*',s))
None
>>> print(re.match('1. *', s, re.I))
None
>>> re.findall('[a-z]{3}', s)
['ife', 'can', 'goo']
>>> re.findall('[a-z]{1,3}',s)
['ife', 'can', 'be', 'goo', 'd']
>>> 

13.2.2 sub()与subn()函数
在这里插入图片描述
在这里插入图片描述

>>> import re
>>> s = 'Life can be bad'
>>> re.sub('bad', 'good', s)
'Life can be good'
>>> re.sub('bad|be', 'good', s)
'Life can good good'
>>> re.sub('bad|be', 'good', s, 1)
'Life can good bad'
>>> re.subn('bad|be', 'good', s, 1)
('Life can good bad', 1)
>>> r = re.subn('bad|be', 'good', s)
>>> print(r[0])
Life can good good
>>> print(r[1])
2
>>> 

13.2.3 split()函数
re.split()函数用于分割字符串,它返回分割后的字符串列表。其函数原型分别如下。
在这里插入图片描述
注意 该函数返回的数据类型为列表。
在这里插入图片描述
在这里插入图片描述
13.2.4 正则表达式对象这部分演示了,但是没有保存下来
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
13.3 分组匹配与匹配对象使用

在正则表达式中使用组,可以将正则表达式分解成几个不同的组成部分。在完成匹配或者搜索后,可以使用分组编号访问不同部分匹配的内容。

13.3.1 分组基础

在正则表达式中以一对圆括号“()”来表示位于其中的内容属于一个分组。例如“(re)+”将匹配“rere”、“rerere”等多个“re”重复的情况。分组在匹配由不同部分组成的一个整体时非常有用。如电话号码由区号和号码组成,在正则表达式中可以使用两个分组来进行匹配:一个分组匹配区号,另一个分组匹配后边的号码。在交互式环境下演示代码如下:

在这里插入图片描述
在这里插入图片描述
13.3.2 分组扩展

除了在组中使用“(?P<组名>)”来命名组名以外,还可以使用几种以“?”开头的扩展语法,如表13.3所示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

>>> import re
>>> s = '''Life can be good;
... Life can be bad;
... Life is mostly cheerful;
... But sometimes sad.
... '''
>>> r = re.compile(r'be(?=\sgood)')
>>> m = r.search(s)
>>> m
<re.Match object; span=(9, 11), match='be'>
>>> m.span()
(9, 11)
>>> r.findall(s)
['be']
>>> r = re.compile('be')
>>> r.findall(s)
['be', 'be']
>>> r = re.compile(r'be(?!\sgood)')
>>> m = r.search(s)
>>> m
<re.Match object; span=(27, 29), match='be'>
>>> m.span()
(27, 29)
>>> r = re.compile(r'(?:can\s) be (\sgood)')
>>> m = r.search(s)
>>> m
>>> m.groups()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'groups'
>>> r = re.compile(r'(?:can\s)be(\sgood)')
>>> m = r.search(s)
>>> m
<re.Match object; span=(5, 16), match='can be good'>
>>> m.groups()
(' good',)
>>> m.groups(1)
(' good',)
>>> r = re.compile(r'(?P<first>\w)(?P=first)')
>>> r.findall(s)
['o', 'e']
>>> r = re.compile(r'(?<=can\s)b\w*\b')
>>> r.findall(s)
['be', 'be']
>>> r = re.compile(r'(?<!can\s)(?i)b\w*\b')
<stdin>:1: DeprecationWarning: Flags not at the start of the expression '(?<!can\\s)(?i)b\\w*\\b'
>>> r = re.compile(r'(?<!can\s)(?i)b\w*\b')
>>> r.findall(s)
['bad', 'But']
>>> 

13.3.3 匹配对象与组的使用

Match对象实例是由正则表达式对象的match、search方法在匹配成功后返回的。Match对象有以下常用的方法和属性,用于对匹配成功的正则表达式进行处理。

group()、groups()、groupdict()方法都是处理在正则表达式中使用“()”分组的情况。不同的是,group()的返回值为字符串,当传递多个参数时其返回值为元组;groups()的返回值为元组;groupdict()的返回值为字典。其原型分别如下:

group( [group1, …])
groups( [default])
groupdict( [default])

对于group(),其参数为分组的编号。如果向group()传递多个参数,则其返回各个参数所对应的字符串组成元组。对于groups()和groupdict()一般不需要向其传递参数。

在这里插入图片描述
在这里插入图片描述

>>> s = '''Life can be dreams,
... Life can be great thoughts;
... Life can mean a person,
... Sitting in a court.'''
>>> r = re.compile('\\b(?P<first>\w+)a(\w+)\\b')
>>> m = r.search(s)
>>> m.groupdict()
{'first': 'c'}
>>> m.groups()
('c', 'n')
>>> m.groupdict()
{'first': 'c'}
>>> m = r.search(s,9)
>>> m.group()
'dreams'
>>> m.group(1)
'dre'
>>> m.group(2)
'ms'
>>> m.group(1,2)
('dre', 'ms')
>>> m.groupdict()
{'first': 'dre'}
>>> m.groups()
('dre', 'ms')
>>> 

13.3.4 匹配对象与索引使用

start()、end()、span()方法返回所匹配的子字符串的索引。其原型分别如下:

start( [groupid=0])
end( [groupid=0])
span( [groupid=0])

其参数含义相同,groupid为可选参数,即分组编号。如果不向其传递参数,则返回整个子字符串的索引。start()方法返回子字符串或者组的起始位置索引。end()方法返回子字符串或者组的结束位置索引。而span()方法则以元组的形式返回以上两者。

在这里插入图片描述
在这里插入图片描述

>>> r = re.compile('\\b(?P<first>\w+)a(\w+)\\b')
>>> m = r.search(s,9)
>>> m.start()
12
>>> m.start(1)
12
>>> m.start(2)
16
>>> m.end(1)
15
>>> m.end()
18
>>> m.span()
(12, 18)
>>> m.span(2)
(16, 18)
>>> 

13.4 正则表达式应用示例

正则表达式是处理文本文件的强有力工具。本节中给出一个简单地使用正则表达式处理Python程序中的函数和变量的例子。

在Python程序中,函数定义必须以“def”开头,因此处理函数的过程相当简单。为了代码简洁,此处假设程序编写规范上在关键字“def”后跟一个空格,然后就是函数名,接着就是参数。没有考虑使用多个空格的情况。

而Python程序中的变量不好处理,因为变量一般不需要事先声明,往往都是直接赋值。因此在程序中首先处理了变量直接赋值的情况。通过匹配单词后接“=”的情况查找变量名。同样,为了代码简洁,仅考虑比较规范整洁的写法,变量名与“=”之间有一空格。另外,还有一类变量是在for循环语句中直接使用的,因此程序中又特别处理了for循环的情况。为了使代码简洁,程序并没有处理变量名重复的情况。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

>>> import re
>>> import sys
>>> def DealWithFunc(s):
...     r = re.compile(r'''
...             (?<=def\s)
...             \w+
...             \(.*?\)
...             (?=:)
...             ''',re.x|re.U
...     return r.findall(s)
  File "<stdin>", line 8
    return r.findall(s)
    ^
SyntaxError: invalid syntax
>>> def DealWithFunc(s):
...     r = re.compile(r'''
...             (?<=def\s)
...             \w+
...             \(.*?\)
...             (?=:)
...             ''',re.x|re.U)
...     return r.findall(s)
... 
>>> def DealWithVar(s):
...     vars = []
...     r = re.compile(r'''
...         \b
...         \w+
...         (?=\s=)
...         ''',re.x|re.U)
...     vars.extend(r.findall(s))
...     r = re.compile(r'''
...         (?<=for\s)
...         \w+
...         \s
...         (?=in)
...         ''',re.X|re.U
...     vars.extend()
KeyboardInterrupt
>>> def DealWithFunc(s):
...     r = re.compile(r'''
...         (?<=def\s)
...         \w+
...         \(.*?\)
...         (?=:)
...         ''',re.X|re.U)
...     return r.findall(s)
... 
>>> def DealWithVar(s):
...     vars = []
...     r = re.compile(r'''
...         \b
...         \w+
...         (?=\s=)
...         ''',re.X|re.U
...         )
... 
>>> def DealWithVar(s):
...     vars = []
...     r = re.compile(r'''
...         \b
...         \w+
...         (?=\s=)
...         ''',re.X|re.U)
...     vars.extend(r.findall(s))
...     r = re.compile(r'''
...         (?<=for\s)
...         \w+
...         \s
...         (?=in)
...         ''',re.X|re.U)
...     vars.extend(r.findall(s))
...     return vars
... 
>>> if len(sys.argv) == 1:
...     sour = input("请输入要处理的文件路径")
... 
请输入要处理的文件路径
>>> else:
  File "<stdin>", line 1
    else:
    ^
SyntaxError: invalid syntax
>>> if len(sys.argv) == 1:
...     sour = input("请输入要处理的文件路径")
... else:
...     sour = sys.argv[1]
... 
请输入要处理的文件路径
>>> file = open(sour,encoding="utf-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: ''
>>> if len(sys.argv) == 1:
...     sour = sys.argv[1]
... else:
... 
KeyboardInterrupt
>>> if len(sys.argv) == 1:
...     sour = input("请输入要处理的文件路径")
... else:
...     sour = sys.argv[1]
... 

13.5 小结

正则表达式的功能非常强大,学习难度也较大,本章以尽量多的操作代码演示了正则表达式的用法。首先介绍了正则表达式的基本元字符、常用正则表达式分析。接着介绍了使用Python的re模块处理正则表达式,如用match函数进行搜索、使用sub函数进行内容替换、使用split函数分割等。接着介绍了将正则表达式编译为对象,以提供更高性能的方法。还介绍了正则表达式中的分组、匹配和搜索的结果对象——Match对象的使用等内容。以后要多编写代码进行学习、验证。在其他程序设计语言中也可以直接使用在这里学习的正则表达式。

13.6 本章习题
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

ant-design V4升级V5记录(成功篇)

官方文档&#xff1a;https://ant.design/docs/react/migration-v5-cn 1、安装运行工具之前&#xff0c;提交本地修改内容&#xff1b; 2、工具运行完&#xff0c;根据提示修改文件问题&#xff1b; 3、移除config文件中module&#xff0c; [import,{libraryName:antd, libr…

负载均衡上传webshell+apache换行解析漏洞

目录一、负载均衡反向代理下的webshell上传1、nginx负载均衡2、负载均衡下webshell上传的四大难点难点一&#xff1a;需要在每一台节点的相同位置上传相同内容的webshell难点二&#xff1a;无法预测下一次请求是哪一台机器去执行难点三&#xff1a;当我们需要上传一些工具时&am…

Jenkins创建多分支流水线

Jenkins创建多分支流水线一、准备工作二、安装插件1、安装Docker和Docker Pipeline2、安装Blue Ocean3、安装Publish Over SSH三、创建多分支流水线四、配置以及脚本四、构建项目在我们的实际开发过程中&#xff0c;我们势必会存在多个分支进行不同的研发需要&#xff0c;这个时…

【LoRa 与 LoRaWAN】知识点汇总

本文主要记录【LoRa 与 LoRaWAN】知识点汇总&#xff0c;知识均来源于网络&#xff0c;纯属资料汇总与搬运 涉及到lora基本知识点&#xff0c;lora芯片的工作分析&#xff0c;专业名词解释 【LoRa 与 LoRaWAN】知识点汇总1.Lora和LoraWAN的区别2. lora 相关知识点汇总2.1 Lora调…

MG996R舵机介绍

舵机简介舵机是一种位置&#xff08;角度&#xff09;伺服的驱动器&#xff0c;适用于那些需要角度不断变化并可以保持的控制系统。在高档遥控玩具&#xff0c;如飞机、潜艇模型&#xff0c;遥控机器人中已经得到了普遍应用。舵机主要是由外壳、电路板、驱动马达、减速器与位置…

C语言入门教程||C语言 循环||C语言 函数

C语言 循环有的时候&#xff0c;可能需要多次执行同一块代码。一般情况下&#xff0c;语句是顺序执行的&#xff1a;函数中的第一个语句先执行&#xff0c;接着是第二个语句&#xff0c;依此类推。编程语言提供了允许更为复杂的执行路径的多种控制结构。循环语句允许我们多次执…

蓝桥杯刷题021——填字母游戏(DFS)

2017国赛 题目描述 小明经常玩 LOL 游戏上瘾&#xff0c;一次他想挑战 K 大师&#xff0c;不料 K 大师说&#xff1a; "我们先来玩个空格填字母的游戏&#xff0c;要是你不能赢我&#xff0c;就再别玩 LOL 了"。 K 大师在纸上画了一行 n 个格子&#xff0c;要小明和…

go语言的并发编程

并发编程是 Go语言的一个重要特性,而 go语言也是基于此而设计出来的。 本文将会介绍如何使用go-gc中的“runtime”方法实现 go语言中的并发编程。 在之前的文章中,我们已经对 runtime方法进行了详细介绍,这次文章将对 runtime方法进行深入分析,并讲解如何在go-gc中使用该方…

Java NIO学习(二):Channel通道

2.1 Channel 概述Java NIO 的通道类似流&#xff0c;但又有些不同&#xff1a;既可以从通道中读取数据&#xff0c;又可以写数据到通道。但流的读写通常是单向的。通道可以异步地读写。通道中的数据总是要先读到一个 Buffer&#xff0c;或者总是要从一个 Buffer 中写入。2.2 Ch…

PrimoBurner SDK for .NET

PrimoBurner SDK for .NET PrimoBurnerSDK是一个CD、DVD和蓝光刻录工具开发工具包。PrimoBurner是跨平台的&#xff0c;它还提供了一个全面灵活的API&#xff0c;用于快速轻松地实现各种燃烧/翻录替代方案。现在PrimoBurner迫使许多卫生、国防、执法、娱乐和其他部门。 PrimoBu…

面试复习题--性能检测原理

1、布局性能检测 Systrace&#xff0c;内存优化工具中也用到了 Systrace,这里关注 Systrace 中的 Frames 页面&#xff0c;正常情况下圆点为绿色&#xff0c;当出现黄色或者红色的圆点时&#xff0c;表现出现了丢帧。 Layout Inspector&#xff0c;是 AndroidStudio 自带工具…

Python环境搭建、Idea整合

1、学python先要下载什么&#xff1f; 2、python官网 3、idea配置Python 4、idea新建python 学python先要下载什么&#xff1f; python是一种语言&#xff0c;首先你需要下载python&#xff0c;有了python环境&#xff0c;你才可以在你的电脑上使用python。现在大多使用的是pyt…

this指针

目录 一、关于this指针的一个经典问题 二、this指针的特点 &#xff08;一&#xff09;本质 &#xff08;二&#xff09;应用 1. 不使用this指针 2. 使用this指针 3. 两者代码对比 三、代码举例 1. 举例1 2. 举例2 一、关于this指针的一个经典问题 当你进入一个房子…

MySQL面试题:SQL语句的基本语法

MySQL目录一、数据库入门1. 数据管理技术的三个阶段2. 关系型数据库与非关系型数据库3. 四大非关系型数据库a. 基于列的数据库&#xff08;column-oriented&#xff09;b. 键值对存储&#xff08;Key-Value Stores&#xff09;c. 文档存储&#xff08;Document Stores&#xff…

In Context Learning 相关分享

个人知乎详见 https://zhuanlan.zhihu.com/p/603650082/edit 1. 前言 随着大模型&#xff08;GPT3&#xff0c;Instruction GPT&#xff0c;ChatGPT&#xff09;的横空出世&#xff0c;如何更高效地提示大模型也成了学术界与工业界的关注&#xff0c;因此In-context learning…

ArcGIS API for JavaScript 4.15系列(3)——Dojo中的css样式操作

1、前言 前一篇博客介绍了Dojo中基础的dom操作方法&#xff0c;主要是针对html中的常用标签和属性进行操作。而一个优秀的线上网站自然也离不开css样式的从旁辅助。在实际开发过程中&#xff0c;我们经常会遇到需要动态修改css样式的问题&#xff0c;本文就来介绍一下如何在Do…

大数据框架之Hadoop:入门(一)大数据概论

第1章 大数据概论 1.1大数据概念 大数据(Big Data)&#xff1a;指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。 主要解决&#xff…

【java基础】集合

集合 集合类位于java.util 包下&#xff0c;集合类又被称为容器 与数组的区别 数组的长度是固定的&#xff0c;集合的长度是可变的数组可以用来存放基本数据类型&#xff0c;集合存放引用类型&#xff0c;不能存放基本数据类型 如何选择 collection map 黄色的是接口&…

1.计算机基础-操作系统面试题—计算机系统概述、进程管理

本文目录如下&#xff1a;计算机基础-操作系统 面试题一、计算机系统概述CPU 内核态 和 用户态 的区别&#xff1f;从 用户态 切换到 内核态 的常见方法&#xff1a;二、进程管理线程 和 进程 的区别&#xff1f;协程 (goroutine) 和 线程的区别?进程有哪些状态&#xff1f;进…

day11_类中成员之变量

通过以前的学习&#xff0c;我们知道了成员变量是类的重要组成部分。对象的属性以变量形式存在&#xff0c;下面我们就来详解的学习一下类中的变量 成员变量 成员变量的分类 实例变量&#xff1a;没有static修饰&#xff0c;也叫对象属性&#xff0c;属于某个对象的&#xf…