Python中正则表达式讲解

正则表达式是匹配字符串的强大武器,它的核心思想是给字符串定义规则,凡是符合规则的字符串就是匹配了,否则就是不合法的。在介绍Python的用法之前,我们先讲解一下正则表达式的规则,然后再介绍在Python中如何运用。

如果直接给出字符,那么就是精确的匹配,例如‘abc’当然是匹配’abc’了。

  • \d可以匹配数字(0-9)
  • \D和\d相反,就是说只要不是0-9,都可以匹配
  • \w可以匹配字母或者数字(0-9|a-z|A-Z)
  • \W和\w相反,就是说只要不是字母和数字,都可以匹配
  • \s可以匹配空格,\n,\t,\r,\f
  • \S和\s相反
  • . 可以匹配除了\n以外的任意字符

第一步先说这些内容,Python提供re模块,包含所有正则表达式的功能,看下面的程序演示:

#如何判断正则表达式是否匹配,使用re.match()
import re
a=re.match('\d','1')
b=re.match('\d','s')
print(a)
print(b)输出:
<_sre.SRE_Match object at 0x000000000065A510>
None

这里说一下,如果match()方法匹配的话,返回一个Match对象,否则返回None
为了方便观察程序运行结果,我们使用if判断来输出结果,下面再看一个例子

import re
def is_match(a):if a!=None:print('yes!')else:print('no!')
a=re.match('\d','123abc')
b=re.match('\d\d','123abc')
c=re.match('\d\d\d','123abc')
d=re.match('\d\d\d\d','123abc')
is_match(a)
is_match(b)
is_match(c)
is_match(d)输出:
yes!
yes!
yes!
no!

现在来讲解上面的代码,我们知道\d可以匹配一个0-9的数字,所以re.match(‘\d’,’123abc’)中的\d匹配的是字符串‘123abc’中的1,至于后面的’23abc’不用管它。一个\d我只用匹配一个数字就可以了。re.match(‘\d\d’,’123abc’)中的两个\d分别匹配的是字符串’123abc’中的‘1’和‘2’,后面的‘3abc’不用管。re.match(‘\d\d\d\d’,’123abc’)中前3个\d分别匹配的是‘1’,‘2’,‘3’,当第4个\d去匹配‘a’的时候发现不能匹配,所以最后一个不能匹配上,输出None。再看几个例子体会下吧

为了减少代码量,下面的代码我会直接写主要的代码部分,输出结果用注释代替

a=re.match('\w','123abc') #yes
b=re.match('\w','abc123') #yes
c=re.match('\w','Abc123') #yes
a=re.match('.','abc') #yes
b=re.match('.','Abc') #yes
c=re.match('.','12bc') #yes
d=re.match('.','*2bc') #yes
e=re.match('.','\n2bc') #no

如果我们要匹配变长的字符,可以在\d,\w,\s, . 的后面使用下面的符号
* 表示任意个字符(包括0个)
+表示至少一个字符
?表示0个或1个字符
{n}表示n个字符
{n,m}表示n-m个字符

a=re.match('\d*','123') #yes
# *表示任意个字符,包括0个,所以\d*可以匹配0个数字,所以match('\d*','abc')可以匹配
b=re.match('\d*','abc') #yes
c=re.match('\d+','1abc') #yes
# +表示至少1个字符,\d+表示至少1个数字,所以匹配不成功
d=re.match('\d+','abc') #no
a=re.match('\d?','123') #yes
b=re.match('\d?','abc') #yes
c=re.match('\d{3}','1234') #yes
#\d{3}代表3个数字,而'12'只有2个,所以不匹配
d=re.match('\d{3}','12') #no
#'12abc'前3个'12a'不全是数字
e=re.match('\d{3}','12abc') #no
a=re.match('\d{0,3}','abc') #yes
b=re.match('\d{0,3}','12abc') #yes
c=re.match('\d{0,3}','1234bc') #yes

还有更加精确的匹配,用[ ]表示范围,例如:
[0-9]匹配1个数字,和\d一样
[a-z]匹配1个小写字母
[A-Z]匹配1个大写字母
\ _匹配下划线
[0-9a-zA-Z]可以匹配1个数字或者字母,等价于\w
[0-9a-zA-Z\ _]可以匹配1个数字或者字母或者下划线,一般是变量的命名规则
[0-9] | [a-z]匹配1个数字或者小写字母,使用的是 | 符号
^表示以什么开头,例如^[0-9]就是以数字开头
$表示以什么结尾

a1=re.match('[0-9]','123') #yes
a2=re.match('[a-z]','abc') #yes
a3=re.match('[A-Z]','Abc') #yes
a4=re.match('[0-9a-zA-Z]','Abc') #yes
b1=re.match('[0-9a-zA-Z]','12bc') #yes
b2=re.match('[0-9a-zA-Z]','abc') #yes
b3=re.match('[0-9a-zA-Z]','张康abc') #no
b4=re.match('[0-9a-zA-Z\_]','_abc') #yes
a=re.match('^[0-9a-zA-Z\_][0-9]','a1bc') #yes
b=re.match('^[0-9a-zA-Z\_][a-z]','Abc') #yes
c=re.match('^[0-9a-zA-Z\_][A-Z]','1Bbc') #yes
d=re.match('^[0-9a-zA-Z\_][0-9]','1abc') #no
e=re.match('^[0-9a-zA-Z\_]','_1bc') #yes
a=re.match('^[0-9a-z]+[A-Z]$','1234A') #yes
b=re.match('^[0-9a-z]+[A-Z]$','1234a') #no

正则表达式还可以用来切分字符串(切分字符串)

import re
a=re.split('\s+','a  b c')
print(a)输出:
['a', 'b', 'c']

关于字符串中的split()函数,不明白的请参考我的另一篇博文。上面的代码的意思是以空格为切分符,把字符串分成n段,并以list的形式返回。
如果还想把逗号加进去,让空格和逗号都变成分隔符,看下面的代码:

import re
a=re.split('[\s\,]+','a  b c     ,d,f    e')
print(a)输出:
['a', 'b', 'c', 'd', 'f', 'e']

正则表达式还可以用来提取子串(分组)

用( )表示的就是要提取的分组(Group),把想要提取的子串在正则表达式中用( )括起来,例如我要提取带区号的固定电话号的每一部分,看代码演示:

import re
a=re.match('(\d{4})\-(\d{7})','0370-5163700')
g0=a.group(0)
g1=a.group(1)
g2=a.group(2)
print(g0)
print(g1)
print(g2)输出:
0370-5163700
0370
5163700

\d{4}匹配的是0370,因为我要提取它,所以用()括起来,代表一个分组
\ - 匹配的是 - ,因为这里 - 是特殊字符,需要转义,就像下划线需要转义\ _,这里我不需要提取这个 - ,所以不用加括号。
\d{7}匹配的是5163700,这是需要提取的第二个分组,所以需要括起来。
还有一点需要注意,无论什么时候,group(0)提取的都是原来的字符串,你要提取的分组从group(1)开始。

正则表达式的贪婪匹配

正则表达式匹配默认是贪婪匹配,也就是匹配尽可能多的字符,看个例子吧!

import re
a=re.match('^(\d+)(1*)$','12345611111')
print('第一组:'+a.group(1))
print('第二组:'+a.group(2))输出:
第一组:12345611111
第二组:

按照正常的理解\d+应该匹配123456,1*匹配11111,但是由于正则表达式是默认贪婪匹配,\d+匹配了全部数字。怎么才能不让它贪婪匹配呢,很简单,在后面加个问号?就可以了

import re
a=re.match('^(\d+?)(1*)$','12345611111')
print('第一组:'+a.group(1))
print('第二组:'+a.group(2))输出:
第一组:123456
第二组:11111

编译

在Python中使用正则表达式时,re模块内部会干两件事情:

  1. 编译正则表达式,如果正则表达式的字符串本身不合法,会报错;
  2. 用编译后的正则表达式去匹配字符串。

在编写网站的时候,有可能我们会对用户注册时输入的用户名或者邮箱等进行正则验证,那么一个正则表达式可能会匹配成千上万个用户名或者邮箱,每次都需要先编译后匹配,那么效率显得很低。那么为了提高效率,我们可以先编译正则表达式,只需要编译一次,然后用的时候再匹配。

import re
#由字母或者下划线开头,由数字,字母,下划线组成长度为6-20的字符串
re_c=re.compile('^[a-zA-Z\_][\w\_]{5,19}$')
print(re_c.match('a123456789a123456789'))输出:
<_sre.SRE_Match object at 0x000000000065A510>

编译后生成Regular Expression对象,由于该对象自己包含了正则表达式,所以调用对应的方法时不用再次给出正则串。

以上的内容只是正则表达式的九牛一毛,关于其他的正则表达式用法请读者自己查阅,如读者发现错误,欢迎指正。

转载于:https://www.cnblogs.com/neuzk/p/9476429.html

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

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

相关文章

电源适配器上各符号的意义都清楚吗?

现在家里的电子产品是越来越多了&#xff0c;比如&#xff1a;手机、平板、笔记本、智能电视、智能音箱、路由器、剃须刀等&#xff1b;机身或者充电器上都有很多符号标志。 有没有好奇过或者被小孩询问过&#xff0c;这些符号标志都是什么意思呢&#xff1f;只有读懂这些符号…

苏宁海量服务器自动化配置运维实践

运维的演进 人力运维阶段 在IT产业的早期&#xff0c;服务器运维是通过各种Ad Hoc命令或者Shell脚本来完成基础设施的自动化工作&#xff0c;这种方式对于简单&#xff0c;一次性的工作很方便&#xff0c;但是对于复杂和长期的项目&#xff0c;后期的脚本维护非常麻烦。自动化工…

JS小技巧

JS操作伪元素 CSS代码&#xff1a; #myId:before {content: "hello world!";display: block;width: 100px;height: 100px;background: red; } JS 代码&#xff1a; var myIdElement document.getElementById("myId"); var beforeStyle window.getCompute…

流媒体服务器

1 引言   随着互联网的飞速发展,流媒体技术的应用越来越广泛,从网上广播、电影播放到远程教学以及在线的新闻网站等都用到了流媒体技术。但现有公开文献所报道 的大多是利用现有的流媒体服务器来搭建一个流媒体服务系统&#xff0c;或者是针对流媒体数据的编码方式所进行的…

试产机器发现元器件损毁 风险排查过程

产品在试产阶段或者公测阶段&#xff0c;发现有个别机器功能异常&#xff0c;研发定位为个别元器件损坏&#xff1b; 定位过程大致有如下步骤&#xff1a; A-故障现象复现 B-输入输出检查 C-电源及管脚状态测量 D-交叉验证 E-基本外观观察和特性测量 然后将器件邮寄给原…

腾讯面试经验2

时间&#xff1a;2017年10月16日11:30面试。 地点&#xff1a;重庆万达艾美酒店。 信息&#xff1a;女&#xff0c;本科应届生&#xff0c;面试后台开发岗位。 在深圳的面试已经全部结束了&#xff0c;偶然间听朋友说重庆、长沙等场地的面试还在进行中&#xff0c;只要修改面试…

简易有效Api接口防攻击策略

API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;是一些预先定义的函数&#xff0c;目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力&#xff0c;而又无需访问源码&#xff0c;或理解内部工作机制的细节。 简单…

CSS 如何设置垂直居中

1、水平居中我们都知道&#xff0c;可以直接用&#xff1a; margin:0 auto; 2、垂直居中&#xff0c;需要做一点小小的计算&#xff0c;关键代码如下&#xff1a; height: 600px; position: absolute; top: 50%; margin-top:-300px; 如需水平且垂直居中&#xff1a; height: 60…

被称为海淀妈妈四大神器之一的倾听者K3 硬件拆解

暑假期间发现很多博主都在推荐倾听者K3&#xff0c;被海淀妈妈们称为四大神器之一&#xff0c; 虽然暂没听说其他三大神器是什么&#xff0c;作为教育硬件爱好者还是决定先整个回来拆拆看。 在京东上搜到倾听者K3版本一共有三种颜色&#xff0c;分别是蓝色&#xff08;悟空蓝&…

有名信号量sem_open和内存信号量sem_init创建信号量的区别

有名信号量sem_open和内存信号量sem_init创建信号量的区别 分类&#xff1a; C/C sem_t *sem sem_open(const char *name, int oflag, .../*mode_t mode,unsinged int value) ;int sem_init(sem_t *sem,int shared, unsigned int value);区别&#xff1a;1.创建有名信号量必须…

KVM虚拟机相关步骤

KVM是Kernel-based Virtual Machine的简称&#xff0c;是一个开源的虚拟化模块&#xff0c;该文档是基于CentOS 7.4环境操作的 一、操作系统安装 本文采用的是CentOS 7.4 1、查看系统版本 cat /etc/redhat-release 2、系统更新 Yum makecache &&yum update && …

dds设计信号发生器

高一 150206101 Dds数字信号发生器设计方案 DDS的工作原理框图如下 在微机内&#xff0c;若插入一块D/A转换卡&#xff0c;然后编制一段小程序&#xff0c;如连续进行加一运算到一定值&#xff0c;然后连续进行减一 运算回到原值&#xff0c;在反复运行该程序&#xff0c;则微机…

Maven--资源文件resource的问题

2019独角兽企业重金招聘Python工程师标准>>> Maven项目的目录有&#xff1a; src/java/main src/java/resource src/test/main src/test/resource 有的时候在resource目录下添加文件却不能加载出来&#xff0c;解决的办法是从把添加的资源文件添加到properties---&g…

pthread_create()创建线程最大个数

线程应用程序最常见导致创建线程失败的原因是线程栈大小的设置。创建一个新的线程&#xff0c;默认情况下系统为线程栈预留了2MB的寻址空间。线程栈起始于进程虚拟 内存的高端地址&#xff0c;并向虚拟内存底端地址方向扩展。取决于线程本身的大小以及其它线程内存分配的情况&a…

C++ Primer 5 CH4 表达式

4.1 基础 函数调用也是一种特殊的运算符&#xff0c;它对运算对象的数量没有限制。C 的表达式要么是左值&#xff0c;要么是右值。左值可以位于赋值语句的左边&#xff0c;右值则不可以。当一个对象被用作右值的时候&#xff0c;用的是对象的值&#xff1b;当对象被用作左值的时…

PHY以太网自动协商原理

自协商原理&#xff1a;自协商是通过一种叫做快速连接脉冲&#xff08;Fast Link Pulse&#xff09;的信号实现的&#xff0c;简称FLP。自协商的双方通过FLP来交换数据。 在具备自协商能力的端口没有Link的情况下&#xff0c;端口一直发送FLP&#xff0c;在FLP中包含着…

canvas--初级

摘要&#xff1a; canvas:默认宽高为300*150&#xff0c;需用canvas的API定义其宽高绘画路径以beginPath()开始,以closePath()结束常用方法fill()、stroke()、rect()、arc()、text()、lineTo()、moveTo()以下为代码&#xff1a; var cdocument.getElementById("mycanvas&q…

扑克牌翻牌问题(递归)

扑克牌翻牌问题 题目描述&#xff1a; 有52张牌&#xff0c;使它们全部正面朝上&#xff0c;从第2张开始&#xff0c;凡是2的倍数位置上的牌翻成正面朝下&#xff1b;接着从第3张牌开始&#xff0c;凡是3的倍数位置上的牌&#xff0c;正面朝上的翻成正面朝下,正面朝下的翻成正面…

以太网自动协商原理

自协商基本原理 自动协商模式是端口根据另一端设备的连接速度和双工模式&#xff0c;自动把它的速度调节到最高的公共水平&#xff0c;即线路两端能具有的最快速度和双工模式。 自协商功能允许一个网络设备能够将自己所支持的工作模式信息传达给网络上的对端&#xff0c;并接受…

Python学习-文件的调用-读取

1.文件的打开 open(filename[,mode[,buffering]]) #这个一定要记得关文件。close.() filename,要以路径的形式展示&#xff0c;比如在"c:\"中&#xff0c;则要这样写: rc:\filename 如果不用路径展示&#xff0c;那就用filename.其会在执行文件所在的文件夹进行搜索…