当前位置: 首页 > 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.lryc.cn/news/584777.html

相关文章:

  • Vue 中监测路由变化时,通常不需要开启深度监听(deep: true)
  • Spring事务管理深度解析:原理、实践与陷阱
  • STM32-ADC
  • squash压缩合并
  • 计算机视觉速成 之 概述
  • 【学习笔记】机器学习(Machine Learning) | 第七章|神经网络(2)
  • Linux:库的原理
  • (C++)任务管理系统(文件存储)(正式版)(迭代器)(list列表基础教程)(STL基础知识)
  • 【算法笔记 day three】滑动窗口(其他类型)
  • 使用球体模型模拟相机成像:地面与天空的可见性判断与纹理映射
  • STM32第十九天 ESP8266-01S和电脑实现串口通信(2)
  • Linux 日志分析核心命令速查表
  • UE5源码模块解析与架构学习
  • 【第二节】ubuntu server配置静态IP
  • 蜻蜓I即时通讯系统重构宣言:破茧重生的技术革命-长痛不如短痛卓伊凡|麻子|果果
  • 【HTTP服务端】Cookie?Session?Token?
  • Spring Boot项目中大文件上传的优化策略与实践
  • LVGL学习笔记-----进度条控件(lv_bar)
  • 攻防世界——web题catcat-new session值伪造
  • Linux驱动学习day21(GPIO子系统)
  • 查看uniapp 项目中没有用到依赖
  • 【IO复用】五种IO模型
  • 1. COLA-DDD的实战
  • 抽象类与接口:Java面向对象设计的两大支柱
  • 中文分词:分词工具及使用实践总结
  • 26-计组-外存
  • Docker-构建镜像并实现LNMP架构
  • 差分和前缀和
  • day01 - 数组part01
  • 如何安装python以及jupyter notebook