python正则表达式详解笔记,python正则表达式教学

正则表达式

正则表达式是一个特殊的字符序列,计算机科学的一个概念。通常被用来检索、替换那些符合某个模式(规则)的文本。

许多程序设计语言都支持利用正则表达式进行字符串操作。在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用re模块。re 模块使 Python 语言拥有全部的正则表达式功能。

特点:

灵活性、逻辑性和功能性非常强;

可以迅速地用极简单的方式达到字符串的复杂控制。

对于刚接触的人来说,比较晦涩难懂。

Python中的正则表达式

与大多数编程语言相同,正则表达式里也使用\作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符\,那么使用编程语言表示的正则表达式里将需要4个反斜杠\:前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。

print(re.match('\\\\', '\hello'))  # 需要使用四个反斜杠来匹配一个 \

Python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。在Python 字符串前面添加r即可将字符串转换成为原生字符串。

print(re.match(r'\\', '\hello')) # 使用两个反斜杠即可匹配一个 \

查找方法的使用

在Python中的查找匹配方法,常见的有下面四种,他们的用法大致相同,但是匹配出的结果却不同。

  • match方法(只匹配字符串开头)
  • search方法(扫描整个字符串,找到第一个匹配)
  • findall方法(扫描整个字符串,找到所有的匹配)
  • finditer方法(扫描整个字符串,找到所有的匹配,并返回一个可迭代对象)

match方法的使用

re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

函数语法:

re.match(pattern,string,flags=0)

参数

描述

pattern

匹配的正则表达式

string

要匹配的字符串。

flags

标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

我们可以使用group(num)函数来获取匹配表达式。

import re
result1 = re.match(r'H','Hello')
result2 = re.match(r'e','Hello')
print(result1.group(0)) # 'H' 匹配到的元素
print(result1.span()) # (0,1) 匹配到的元素所在位置
print(result2)  # None

search方法的使用

re.search 扫描整个字符串并返回第一个成功的匹配。

函数语法:

re.search(pattern, string, flags=0)

示例:

import re
result1 = re.search(r'He','Hello')
result2 = re.search(r'lo','Hello')
 
print(result1.group(0))  # He
print(result1.span()) # (0,2)
print(result2.group(0)) # lo
print(result2.span()) # (3,5)

re.match与re.search的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

示例:

result1 = re.search(r'天气','今天天气不错哟')
result2 = re.match(r'天气','今天天气不错哟')
print(result1)  # <re.Match object; span=(2, 4), match='天气'>
print(result2) # None

findall 方法的使用

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

注意: match 和 search 是匹配一次 findall 匹配所有。

语法格式:

re.findall(pattern,string,flags=0)

示例代码:

ret = re.findall(r'\d+','he23ll34')
print(ret)  # ['23', '34']
ret = re.match(r'\d+','he23ll34') 
print(ret) # None match只匹配开头,所以匹配到
ret = re.search(r'\d+','he23ll34')
print(ret) # <re.Match object; span=(2, 4), match='23'> search 只能匹配到一个数字

注意事项:

findall方法匹配时,如果匹配规则里有分组,则只匹配分组数据。

ret = re.findall(r'\w+@(qq|126|163)\.com','123@qq.com;aa@163.com;bb@126.com')
print(ret)  # ['qq', '163', '126']  只匹配到了分组里的内容

如果正则表达式里存在多个分组,则会把多个分组匹配成元组。

ret = re.findall(r'\w+@(qq|126|163)(\.com)','123@qq.com;aa@163.com;bb@126.com')
print(ret) #[('qq', '.com'), ('163', '.com'), ('126', '.com')]

如果想要让findall匹配所有的内容,而不仅仅只是匹配正则表达式里的分组,可以使用 ?:来将分组标记为非捕获分组。

ret = re.findall(r'\w+@(?:qq|126|163)\.com','123@qq.com;aa@163.com;bb@126.com')
print(ret) # ['123@qq.com', 'aa@163.com', 'bb@126.com']

finditer方法的使用

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

ret = re.finditer(r'\d+','he23ll34'# 得到的结果是一个可迭代对象for x in ret: # 遍历 ret 取出里面的每一项匹配
    print(x.group(), x.span()) # 匹配对象里的group保存了匹配的结果

re.Match类介绍

当我们调用re.match方法、re.search方法,或者对re.finditer方法的结果进行迭代时,拿到的数据类型都是re.Match对象。

x = re.match(r'h','hello')
y = re.search(r'e','hello')
z = re.finditer(r'l','hello')
print(type(x))  # <class 're.Match'>
print(type(y)) # <class 're.Match'>for a in z:
    print(type(a)) # <class 're.Match'>

这个类里定义了相关的属性,可以直接让我们来使用。

属性和方法

说 明

pos

搜索的开始位置

endpos

搜索的结束位置

string

搜索的字符串

re

当前使用的正则表达式的对象

lastindex

最后匹配的组索引

lastgroup

最后匹配的组名

group(index=0)

某个分组的匹配结果。如果index等于0,便是匹配整个正则表达式

groups()

所有分组的匹配结果,每个分组的结果组成一个列表返回

groupdict()

返回组名作为key,每个分组的匹配结果座位value的字典

start([group])

获取组的开始位置

end([group])

获取组的结束位置

span([group])

获取组的开始和结束位置

expand(template)

使用组的匹配结果来替换模板template中的内容,

并把替换后的字符串返回

ret = re.search(r'(abc)+', 'xxxabcabcabcdef')
print(ret.pos)  # 搜索开始的位置,默认是0
print(ret.endpos)  # 搜索结束的位置,默认是字符串的长度
print(ret.group(0)) # abcabcabc 匹配整个表达式
print(ret.group(1))  # abc 第一次匹配到的结果
print(ret.span()) # (3, 12) 开始和结束位置
print(ret.groups())  # 表示当正则表达式里有多个分组时,多个分组的匹配结果

re.compile方法的使用

我们在使用正则表达式时,可以直接调用re 模块的 match,search,findall等方法,传入指定的正则表达式。同时,也可以调用re.compile方法,生成一个正则表达式对象,再调用这个正则表达式对象的相关方法实现匹配。

示例:

re.match(r'h','hello'# 可以使用re.match方法直接匹配# 也可以调用re模块的compile方法,生成一个 Pattern 对象,再调用 Pattern 对象的 match方法
regex = re.compile(r'h')
regex.match('hello')
 
re.search(r'l','hello')
regex = re.compile(r'l')
regex.match('hello')
 
regex = re.compile(r'l')
regex.findall('hello')
 
regex = re.complie(r'l')
regex.finditer('hello')

正则表达式修饰符

修饰符

描述

re.I

使匹配对大小写不敏感

re.M

多行匹配,影响 ^ 和 $

re.S

使 . 匹配包括换行在内的所有字符

示例:

print(re.search(r'L','hello'))  # None
print(re.search(r'L', 'hello', re.I))  # 不区分大小写<re.Match object; span=(2, 3), match='l'>
# \w+$ 表示匹配以一个或者多个字母结尾# re.M 可以进行多行匹配,每个换行都认为是一个结尾
print(re.findall(r'\w+$','i am boy\n you are girl\n he is man',re.M)) # ['boy', 'girl', 'man']# 不实用re.M修饰符,只会匹配到最后的 man
print(re.findall(r'\w+$','i am boy\n you are girl\n he is man')) # ['man']
 
print(re.search(r'.','\n')) # None . 匹配除了 \n 以外的所有字符
print(re.search(r'.','\n',re.S)) # '\n'  匹配到了 \n

正则表达式模式

模式字符串使用特殊的语法来表示一个正则表达式:

字母和数字表示他们自身,一个正则表达式模式中的字母和数字匹配同样的字符串。

re.search(r'H','Hello'# 这里的 H 表示的就是字母 H 自身,代表有特殊含义

多数字母和数字前加一个反斜杠时会拥有不同的含义。

ret = re.search(r'\d','he12ms90') # 这里的 \d 表示的是匹配数字

标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

ret = re.search(r'.','hello') # 这里的 . 表示的是匹配任意字符
ret = re.search(r'\.','he.llo'# 这里的 \. 进行了转义,才表示标点符号自身。

反斜杠本身需要使用反斜杠转义。由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于\\t )匹配相应的特殊字符。

下表列出了正则表达式模式语法中的特殊元素,如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

非打印字符

非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:

字符

描述

\cx

匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。

x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。

\f

匹配一个换页符。等价于 \x0c 和 \cL。

\n

匹配一个换行符。等价于 \x0a 和 \cJ。

\r

匹配一个回车符。等价于 \x0d 和 \cM。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。

’注意 Unicode 正则表达式会匹配全角空格符。

\S

匹配任何非空白字符。等价于 [^ \f\n\r\t\v]

\t

匹配一个制表符。等价于 \x09 和 \cI。

\v

匹配一个垂直制表符。等价于 \x0b 和 \cK。

特殊字符

所谓特殊字符,就是一些有特殊含义的字符。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符:

特殊字符

描述

( )

标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。

要匹配这些字符,请使用 \( 和 \)

.

匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \.

[

标记一个中括号表达式的开始。要匹配 [,请使用 \[

\

将下一个字符标记为或特殊字符、或原义字符、或向后引用、

或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符, \\ 匹配 \,而 \( 则匹配 ( 。

{

标记限定符表达式的开始。要匹配 {,请使用 \{

|

指明两项之间的一个选择。要匹配 |,请使用 \|。

\d

匹配一个数字字符。等价于 [0-9]。

[0-9]

匹配任何数字。等价于 \d

\D

匹配一个非数字字符。等价于 [^0-9]

[a-z]

匹配任何小写字母

[A-Z]

匹配任何大写字母

[a-zA-Z0-9]

匹配任何字母及数字。等价于\w

\w

匹配包括下划线的任何单词字符。等价于[A-Za-z0-9_]

\W

匹配任何非单词字符。等价于 [^A-Za-z0-9_]

[\u4e00-\u9fa5]

匹配纯中文

定位符

定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。

定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

正则表达式的定位符有:

特殊字符

描述

^

匹配输入字符串的开始位置,例如:^h匹配以h开头;在方括号表达式中时,

它表示不接受该字符集合,例如[^0-9]匹配除了数字以外的数据。要匹配 ^ 字符本身,请使用 \^。

$

匹配输入字符串的结尾位置。要匹配 $ 字符本身,请使用 \$

\b

匹配一个单词边界,即字与空格间的位置。

\B

非单词边界匹配。

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。

正则表达式的限定符有:

字符

描述

*

匹配前面的子表达式零次或多次。例如,zo 能匹配 "z" 以及 "zoo"。 等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",

但不能匹配 "z"。+ 等价于 {1,}。

?

匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、

"does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。

{n}

n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',

但是能匹配 "food" 中的两个 o。

{n,}

n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',

但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。

{n,m}

m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。

例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。

请注意在逗号和两个数之间不能有空格。

示例:

re.search(r'\s','大家好 我是 代码'# 匹配所有的空字符
re.search(r'\S','大家') # 匹配所有的非空字符
re.search(r'\n','大家好\n我是代码') # 匹配换行
re.search(r'n$','hello python') # 匹配以 n 结尾
re.search(r'^h.+n$','hello python') # 匹配以 h 开头,中间出现一次或多次任意字符,并且以n结尾
re.search(r'^ha*','h'# 匹配以 h 开头,a出现0次或者一次

正则替换

Python中的re模块提供了re.sub用户替换字符串中的匹配项。

语法:

re.sub(pattern,repl,string,count=0)

参数:

  • pattern : 正则中的模式字符串。
  • repl : 替换的字符串,也可为一个函数。
  • string : 要被查找替换的原始字符串。
  • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
phone = "2004-959-559 # 这是一个电话号码"
# 删除注释
num = re.sub(r'#.*$', "", phone)print ("电话号码 : ", num)
# 移除非数字的内容
num = re.sub(r'\D', "", phone)print ("电话号码 : ", num)

repl可以使用一个字符串用来表示替换后的结果以外,还可以传入一个函数。

def double(matched):
    test = int(matched.group('test'))
    return str(test * 2)
 
 
print(re.sub(r'(?P<test>\d+)', double, 'hello23hi

贪婪和非贪婪模式

Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;

非贪婪则相反,总是尝试匹配尽可能少的字符。

*,?,+,{m,n}后面加上 ?使贪婪变成非贪婪。

>>> s="This is a number 234-235-22-423">>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)>>> r.group(1)'4-235-22-423'>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)>>> r.group(1)'234-235-22-423'
>>>

正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。

>>> re.match(r"aa(\d+)","aa2343ddd").group(1)'2343'>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)'2'>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1) '2343'>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)'2343'
>>>

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

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

相关文章

Exploiting Proximity-Aware Tasks for Embodied Social Navigation 论文阅读

论文信息 题目&#xff1a;Exploiting Proximity-Aware Tasks for Embodied Social Navigation 作者&#xff1a;Enrico Cancelli&#xff0c; Tommaso Campari 来源&#xff1a;arXiv 时间&#xff1a;2023 Abstract 学习如何在封闭且空间受限的室内环境中在人类之间导航&a…

uniapp 获取 view 的宽度、高度以及上下左右左边界位置

<view class"cont-box"></view> /* 获取节点信息的对象 */ getElementRect() {const query uni.createSelectorQuery().in(this);query.select(".cont-box").boundingClientRect(res > {console.log(res);console.log(res.height); // 10…

Taro UI中的AtTabs

TaroUI 中的 AtTabs 是一个用于创建标签页(tab)组件的组件。它提供了一种简单的方式来切换显示不同的内容。 AtTabs 的使用方式如下&#xff1a; 首先&#xff0c;引入 AtTabs 组件和必要的样式&#xff1a; import { AtTabs, AtTabsPane } from taro-ui import taro-ui/dis…

Kubernetes系列-删除deployment和pod

通过deployment创建的pod直接执行delete是不会正常被删除的&#xff0c;因为deployment中设置了pod的数量&#xff0c;deployment会动态维护pod的数量&#xff0c;倘若pod数量少于约定数量&#xff0c;deployment会创建pod&#xff0c;直到pod数量达到约定数量才会停止。 如若…

mysql数据库第十二课------mysql语句的拔高2------飞高高

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

研发工程师玩转Kubernetes——通过PV的节点亲和性影响Pod部署

在《研发工程师玩转Kubernetes——PVC通过storageClassName进行延迟绑定》一文中&#xff0c;我们利用Node亲和性&#xff0c;让Pod部署在节点ubuntud上。因为Pod使用的PVC可以部署在节点ubuntuc或者ubuntud上&#xff0c;而系统为了让Pod可以部署成功&#xff0c;则让PVC与Pod…

Spring-Cloud-Loadblancer详细分析_2

LoadBalancerClients 终于分析到了此注解的作用&#xff0c;它是实现不同服务之间的配置隔离的关键 Configuration(proxyBeanMethods false) Retention(RetentionPolicy.RUNTIME) Target({ ElementType.TYPE }) Documented Import(LoadBalancerClientConfigurationRegistrar…

Mongodb:业务应用(1)

环境搭建参考&#xff1a;mongodb&#xff1a;环境搭建_Success___的博客-CSDN博客 需求&#xff1a; 在文章搜索服务中实现保存搜索记录到mongdb 并在搜索时查询出mongdb保存的数据 1、安装mongodb依赖 <dependency><groupId>org.springframework.data</groupI…

Intellij IDEA 导入 eclipse web 项目详细操作

Eclipse当中的web项目都会有这两个文件。但是idea当中应该是没有的&#xff0c;所以导入会出现兼容问题。但是本篇文章会教大家如何导入&#xff0c;并且导入过后还能使用tomcat运行。文章尽可能以图片的形式进行演示。我的idea使用的版本是2022.3.3版本。当然按正常来说版本之…

查询树形目录(内存遍历成树返回)

实体 Data TableName("dtp_sm_servicetype") ApiModel(value "SmServicetype对象", description "服务类型") EqualsAndHashCode(callSuper true) public class SmServicetype extends BaseEntity {ApiModelProperty("服务类型名称&quo…

C++ ModBUS TCP客户端工具 qModMaster 介绍及使用

qModMaster工具介绍 QModMaster是一个基于Qt的Modbus主站&#xff08;Master&#xff09;模拟器&#xff0c;用于模拟和测试Modbus TCP和RTU通信。它提供了一个直观的图形界面&#xff0c;使用户能够轻松设置和发送Modbus请求&#xff0c;并查看和分析响应数据。 以下是QModM…

图论——最短路算法

引入&#xff1a; 如上图&#xff0c;已知图G。 问节点1到节点3的最短距离。 可心算而出为d[1,2]d[2,3]112,比d[1,3]要小。 求最短路径算法&#xff1a; 1.Floyd(弗洛伊德) 是一种基于三角形不等式的多源最短路径算法。边权可以为负数 表现为a[i,j]a[j,k]<a[i,k]。 …

vue3 使用 element-china-area-data 实现地区选择器

官方地址&#xff1a;https://www.npmjs.com/package/element-china-area-data?activeTabreadme 在线示例&#xff1a;https://plortinus.github.io/element-china-area-data/index.html 实际使用 <el-col :span"12"><el-form-item label"所处城市&…

什么是响应式设计?列举几种实现响应式设计的方法。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是响应式设计&#xff1f;⭐ 实现响应式设计的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏…

Docker安装ElasticSearch/ES 7.4.0

目录 前言安装ElasticSearch/ES安装步骤1&#xff1a;准备1. 安装docker2. 搜索可以使用的镜像。3. 也可从docker hub上搜索镜像。4. 选择合适的redis镜像。 安装步骤2&#xff1a;拉取ElasticSearch镜像1 拉取镜像2 查看已拉取的镜像 安装步骤3&#xff1a;创建容器创建容器方…

android 如何分析应用的内存(十八)终章——使用Perfetto查看内存与调用栈之间的泄露

android 如何分析应用的内存&#xff08;十八&#xff09; 在前面两篇文章中&#xff0c;先是介绍了如何用AS查看Android的堆内存&#xff0c;然后介绍了使用MAT查看 Android的堆内存。AS能够满足基本的内存分析需求&#xff0c;但是无法进行多个堆的综合比较&#xff0c;因此…

ArcGIS Pro基础:【按顺序编号】工具实现属性字段的编号自动赋值

本次介绍一个字段的自动排序编号赋值工具&#xff0c;基于arcgis 的字段计算器工具也可以实现类似功能&#xff0c;但是需要自己写一段代码实现&#xff0c; 相对而言不是很方便。 如下所示&#xff0c;该工具就是【编辑】下的【属性】下的【按顺序编号】工具。 其操作方法是…

FreeRTOS(二值信号量)

资料来源于硬件家园&#xff1a;资料汇总 - FreeRTOS实时操作系统课程(多任务管理) 目录 一、信号量的概念 1、信号量的基本概念 2、信号量的分类 二、二值信号量的定义与应用 1、二值信号量的定义 2、二值信号量的应用 三、二值信号量的运作机制 1、FreeRTOS任务间二值…

可视化绘图技巧100篇基础篇(二)-柱状图

目录 前言 什么是柱状图 柱状图的组成 使用场景 适用场景: 不适用场景:

Spring Web

◆ Spring整合web环境 - Javaweb三大组件及环境特点 - Spring整合web环境的思路及实现 把ApplicationContext放在ServleContent域【listen组件中】中 ContextLoaderListener &#xff1a;部分代码写死了 /*** 配置通用的Spring容器的创建&#xff0c;只需要创建一次就可以*/…