当前位置: 首页 > news >正文

python正则表达式(小白五分钟从入门到精通)

正则表达式,又称规则表达式(Regular Expression),是使用单个字符串来描述、匹配某个句法规则的字符串,常被用来检索、替换那些符合某个模式(规则)的文本。 简单来说,正则表达式就是使用:字符串定义规则,并通过规则去验证字符串是否匹配。 比如,验证一个字符串是否是符合条件的电子邮箱地址,只需要配置好正则规则,即可匹配任意邮箱。 比如通过正则规则: (^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$)  即可匹配一个字符串是否是标准邮箱格式 但如果不使用正则,使用if else来对字符串做判断就非常困难了。

正则的三个基础方法

Python正则表达式,使用re模块,并基于re模块中三个基础方法来做正则匹配。 分别是:match()、search()、findall() 三个基础方法

match()函数

设置注册用户名

从被匹配字符串开头进行匹配, 匹配成功返回匹配对象(包含匹配的信息),匹配不成功返回空。
match()函数的使用形式如下:

match(匹配规则, 被匹配字符串) 

示例代码:

import re
message ='张三、李四、王五、赵六'
result = re.match('张三',message)
print(result)
代码执行结果:
Kre.Match object; span=(0,2), match='张三'>


第3行代码表示从message字符串中匹配"张三,这里参数2并没有用到正则表达式(正则表达式会在8.4.2小节介绍)。由于message中'张三'位于开头,因此可以正确地匹配到。

返回的结果以正则的类型输出,其中span=(0,2)指明匹配的位置,表示在字符串索引号为0~2的位置匹配成功,匹配的内容为"张三’。现将以上代码进行修改,修改后的代码如下:

import re
message ='张三、李四、王五、赵六
result=re.match('三',message)
print(result)
代码执行结果:None


虽然字符三'在message中,但并不位于message的开头,所以匹配不成功

search()函数

search(匹配规则, 被匹配字符串) 搜索整个字符串,找出匹配的。从前向后,找到第一个后,就停止,不会继续向后
search()函数的使用形式如下:

search(匹配规则, 被匹配字符串) 


功能:表示从参数2(字符串类型数据)中查找满足参数1(正则表达式)的内容,如果匹配了多个参数1,只返回第1个匹配成功的信息。

示例代码:

import re
message ='张三、李四、王五、赵六、王五
result=re.search('王五',message)
print(result)
代码执行结果:<re.Match object; span=(6, 8), match='王五'>


由于message中存在两个'王五,因此执行代码后会输出第1个'王五'所在的位置及内容。

findall()函数

findall(匹配规则, 被匹配字符串) 匹配整个字符串,找出全部匹配项
findall()函数的使用形式如下:

findall(匹配规则, 被匹配字符串)


功能:表示从参数2(字符串类型数据)中查找满足参数1(正则表达式)的内容,如果匹配了多个参数1,则返回匹配成功的全部信息。
示例代码:

import re
message ='张三、李四、王五、赵六、王五'
result = re.findall('王五',message)
print(result)代码执行结果:
['王五’,王五’]


findall()并不返回匹配的位置,只返回匹配的全部内容。

元字符匹配

上面只是基础的字符串匹配,正则最强大的功能在于元字符匹配规则。

[xyz]:字符集合,即匹配所包含的任意一个字符。例如[abc]可以匹配plain中的a。[8-2]:字符范围,即匹配指定范围内的任意字符。例如[a-2)可以匹配8到12范围内的任意小写字母。示例代码:

import re
message = 'Python93,C87,Java63,C++88'
result_1 = re.search('[cn]',message)
result_2 = re.findall('[0-9]',message)
result_3 = re.findall('[cn][0-9]',message) 
print(result_1,result_2,result_3)代码执行结果:
<re.Match object; span=(5, 6), match='n'> ['g’, ’3’, '8’, ’7’, '6’, ’3’, 'g’, '8'] 「'n9']


第3行代码表示从message中匹配字符c或n,只要message中包含c或n,执行代码后就会输出匹配到的第第4行代码表示从message中匹配0~9的任何一个数字,即匹配全部数字,由于使用了findall()函数,因此1个字符。需要注意的是大写的C是不能匹配的。
程序会将message中的全部数字输出。第5行代码中的正则表达式包含[cn][0-9],表示需要匹配两个字符,且第1个字符是c或n、第2个字符是数字。

数量匹配:

边界匹配:

实例代码:

import re
message = 'da2a7ddbre77yifed777t3fefd7777b'
result = re.findall('[a-z]*[0-9][a-z]',message)#前面的字母可以出现零到无数次"*"
print(result)  代码执行结果:
['da2a', "7d',7y',"7t’,'3f','7b']

 *和+的区别

*:匹配前面的子表达式任意次(大于等于0次)。
+:匹配前面的子表达式一次或多次。

示例代码(验证手机号码的正确性):

import re
phone_num = input("请输入您的手机号码:")#13155558888
result = re.findall('^1[0-9]{10}$',phone_num)
print(result)

当用户输入的内容超过11位或不足11位时,则不满足手机码的要求,与正则表达式不匹配,程序将返回几。例如输入错误的手机号码1377772,验证结果如下:

请输入您的手机号码:1377772
[]

当用户输入的手机号码与正则表达式相匹配时,代码程序将输出匹配的内容。例如输入正确的手机号码15155555555,验证结果如下:

请输入您的手机号码:15155555555
[15155555555]

示例代码(验证QQ号码是否合规):

import re
QQ_number = input("请输入您的QQ号:")
result = re.match('[1-9][0-9]{4,10}$',QQ_number)
print(result)

单字符匹配: 

\d:匹配一个数字类字符,等价于[0-9]。
\D:匹配一个非数字类字符,等价于[^0-9],^在中括号中属于非,即不匹配输入字符的首位字符。
\s:匹配任何不可见字符,包括空格、制表符、换页符等,等价于[\f \n\r\t\v]。
\S:匹配任何可见字符,等价于[^\f \n\r\t\v]。
\w:匹配包括下画线的任何单词字符,等价于"[A-Za-z0-9_]"。
\W:匹配任何非单词字符,等价于"[^A-Za-z0-9_]"。
\f:匹配一个分页符。
\n:匹配一个换行符。
\r:匹配一个Enter键符。
\t:匹配一个制表符。
\v:匹配一个垂直制表符。
.:匹配除"\n"和"\r"之外的任何单个字符。

示例代码(验证用户名的正确性):

import re
use_name = input("请输入您的用户名:")
result = re.findall('^[A-Za-z_]\w{7,}$',use_name)
print(result)

代码执行结果1(输入正确的用户名):

请输入您的用户名:chaoxiang1234
['chaoxiangl234']

代码执行结果2(输入错误的用户名):

请输入您的用户名:chaoxiang1234#
[]

示例代码(匹配非单词边界):

import re
message = 'verb very never every'
result = re.findall(r'\w+er\B',message)  #\b是转义字符
print(result)

代码执行结果:

['ver','ver', 'ever']

由于verb中的er并不是单词的边界,且er的前面有一个单词v,因此此字符串将会被匹配上。very中的ver也能被匹配上。由于never中的er是单词的边界,因此不会被匹配上。every中的er不是单词的边界,且er的前面有单词ev,因此匹配的内容是ever。

import re
message = 'verb very never every'
result = re.findall('.e',message)
print(result)

代码执行结果:

['ve', 've', 'ne', 've', 'e', 've']

其中第1个've'从'verb'中匹配获取;第2个've'从'very'中匹配获取;第3个'ne'从'never'中匹配获取;第个've'从'never'中获取;第5个'e'从'every'中的e和前面的空格匹配获取,由于’.可以匹配除"\n"和"\r"之外的住何单个字符,因此’.e'可以匹配空格和'e';第6个've'从'every'中匹配获取。

贪婪和非贪婪模式

贪婪和非贪婪模式指是否匹配更多内容,具体使用如下。贪婪模式:默认匹配模式都是贪婪模式,匹配形式是尝试匹配尽可能多的字符,只要满足正则表达式要求会匹配最多的字符。
示例代码(默认匹配模式为贪婪模式):

import re
message = 'ccc739134792hd'
result = re.findall('ccc\d+',message)
print(result)

代码执行结果:

['ccc739134792']

由于默认匹配模式是贪婪模式,因此会尽可能多地匹配数字。当从'ccc739134792hd'中匹配到了'ccc7'之后还会继续匹配尽可能多的数字。

非贪婪模式:匹配形式是尝试匹配尽可能少的字符,一旦满足正则表达式要求就不再继续匹配。在次数限制操作符后面加上“?”可以将匹配模式转换为非贪婪模式。

示例代码(将匹配模式转换为非贪婪模式):

import re
message = 'ccc739134792hd'
result = re.findall('ccc\d+?',message)
print(result)

代码执行结果:

['cce7']

正则表达式部分最后增加了一个“?”,表示使用非贪婪模式匹配,只要匹配到'ccc'且后面有一个数字就不会再继续往后匹配。

或和组

如果需要筛选出组合条件下的字符数据,可以使用或。如果需要筛选后的某部分内容,可以使用组。或:用“!”表示,表示将两个匹配条件进行逻辑“或”(or)运算。

示例代码(匹配表达式中两个匹配条件中的一个匹配条件):

import re
message = 'verb very never every'
result = re.findall('\w+ev|\w+ry',message)
print(result)

代码执行结果:

['very', 'nev','every’]

\w+eV表示匹配个或多个单词字符,且后面的字符为ev。“w+ry'表示匹配一个或多个单词字符,且后面的字符为ry。

组:用“(表达式)”表示,表示将(中的表达式定义为组,并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个组)。示例代码(使用组的形式获取组中的内容):

import re
message = 'verb very never every'
result = re.findall("e(.+)(.)r",message)
print(result)

代码执行结果:

[('rb very never ev','e')]

该模式会尽可能多地匹配内容。第2个组匹配除“n”和“”之外的任何单个字符(包含空格)。即从字符串的第1个字符e开始,可以一直匹配到最后一个字符r,因此匹配的内容是'erb very never ever。但输出时只会输出组中的内容,并不会将所有匹配的内容输出,由于有两个组,因此会输出这两个组中的内容。

sub()和 compile()方法

sub()和compile()方法分别用于将字符进行替换和将字符串转换为正则表达式。sub()方法的使用形式如下,即将字符串参数3中所有与参数1匹配的字符替换为参数2。

sub(参数1,参数2,参数3)

 示例代码:

import re
contentl ='2020 12 15 12:00'
pattern = re.compile('\d{2}:\d{2}')
print(pattern.findall(contentl))
import re
content ='dh932hf9f934hfnf39d'
content = re.sub('\d','0',content)
print(content)

代码执行结果:

dh000hfof000nfnf00d

将字符串content中满足正则表达式\d的内容全部替换为0。

compile()方法用于创建一个正则表达式对象,可以直接使用正则表达式对象的方法匹配其他内容。示例代码:

import re
contentl ='2020 12 15 12:00'
pattern = re.compile('\d{2}:\d{2}')
print(pattern.findall(contentl))

代码执行结果:

['12:00']

直接使用pattern,万法的形式,匹配content1中满足pattern正则表达式对象的信息。

http://www.xdnf.cn/news/1099387.html

相关文章:

  • 技术学习_检索增强生成(RAG)
  • 客户频繁问询项目进度,如何提高响应效率
  • STM32中DMA(直接存储器访问)详解
  • 基于 SpringBoot + Vue 的 IT 技术交流和分享平台的设计与实现
  • Git保姆级入门实战:从安装配置到常用命令与常见错误解决
  • 机器学习 YOLOv5手绘电路图识别 手绘电路图自动转换为仿真软件(如LT Spice)可用的原理图,避免人工重绘
  • upload-labs靶场通关详解:第21关 数组绕过
  • H5微应用四端调试工具—网页版:深入解析与使用指南
  • Java 枚举详解:从基础到实战,掌握类型安全与优雅设计
  • 青岛门卫事件后:高温晕厥救援技术突破
  • Transformer:自注意力驱动的神经网络革命引擎
  • PLC框架-1.3.2 报文750控制汇川伺服的转矩上下限
  • 位运算算法题
  • arm架构,arm内核,处理器之间的关系
  • STM32F103之ModBus\RS232\RS422\RS485
  • 记录今天学习Comfyui的感受
  • 【运维架构】云计算运维架构师与基础设施,技术路线,Linux证书(标准化/定制化/CNCF,公有云/混合云/私有云)
  • pharokka phold--快速噬菌体注释工具
  • 1.1.1数据类型与变量——AI教你学Django
  • 一文讲清楚React Hooks
  • Spring for Apache Pulsar->Reactive Support->Quick Tour
  • 【C++】——类和对象(上)
  • C语言<数据结构-链表>
  • Django专家成长路线知识点——AI教你学Django
  • 深度学习参数初始化方法详解及代码实现
  • WebSocket实战:实现实时聊天应用 - 双向通信技术详解
  • [数据结构与算法] 优先队列 | 最小堆 C++
  • C语言——预处理详解
  • Swift 图论实战:DFS 算法解锁 LeetCode 323 连通分量个数
  • 第一次搭建数据库