Python 内置模块之 re

前言

输入一个手机号18333333333,你是怎么知道这串数字是手机号呢,假如现在你用python写一段代码,类似:

phone_number = input('please input your phone number:')

你怎么判断这个phone_number是合法的呢?根据手机号码一共11位并且是只以13、14、15、18开头的数字这些特点,我们用python写了如下代码:

while True:phone_number = input('please input your phone number : ')if len(phone_number) == 11 \and phone_number.isdigit()\and (phone_number.startswith('13') \or phone_number.startswith('14') \or phone_number.startswith('15') \or phone_number.startswith('18')):print('是合法的手机号码')else:print('不是合法的手机号码')

现在换一种写法:

import re
phone_number = input('please input your phone number : ')
if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):print('是合法的手机号码')
else:print('不是合法的手机号码')

上面就是今天我们要学习python里的 re模块和正则表达式

正则表达式不仅在python领域,在整个编程届都占有举足轻重的地位。不管以后你是不是去做python开发,只要你是一个程序员就应该了解正则表达式的基本使用。如果未来你要在爬虫领域发展,你就更应该好好学习这方面的知识。但是 re模块本质上和正则表达式没有一毛钱的关系。re模块和正则表达式的关系 类似于 time模块和时间的关系,他只是正则表达式在python中的实现。正则表达式本身也和python没有什么关系,就是匹配字符串内容的一种规则

官方定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

正则表达式

在线测试工具 http://tool.chinaz.com/regex/

谈到正则,就只和字符串相关了。在提供的工具中,你输入的每一个字都是一个字符串。 其次,如果在一个位置的一个值,不会出现什么变化,那么是不需要规则的。比如你要用”1″去匹配”1″,或者用”2″去匹配”2″,直接就可以匹配上。这连python的字符串操作都可以轻松做到。 那么在之后我们更多要考虑的是在同一个位置上可以出现的字符的范围。

字符组 : [字符组] 在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示 字符分为很多类,比如数字、字母、标点等等。 假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。

正则待匹配字符匹配结果说明
[0123456789]8True在一个字符组里枚举合法的所有字符,字符组里的任意一个字符
和”待匹配字符”相同都视为可以匹配
[0123456789]aFalse由于字符组中没有”a”字符,所以不能匹配
[0-9]7True也可以用-表示范围,[0-9]就和[0123456789]是一个意思
[a-z]sTrue同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示
[A-Z]BTrue[A-Z]就表示所有的大写字母
[0-9a-fA-F]eTrue可以匹配数字,大小写形式的a~f,用来验证十六进制字符

字符

 元字符 匹配内容
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线
\s匹配任意的空白符
\d匹配数字
\n匹配一个换行符
\t匹配一个制表符
\b匹配一个单词的结尾
^匹配字符串的开始
$匹配字符串的结尾
\W匹配非字母或数字或下划线
\D匹配非数字
\S匹配非空白符
a|b匹配字符a或字符b
()匹配括号内的表达式,也表示一个组
[…]匹配字符组中的字符
[^…]匹配除了字符组中字符的所有字符

量词

量词用法说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

. ^ $

正则待匹配字符匹配结果说明
海.海燕海娇海东海燕海娇海东匹配所有”海.”的字符
^海.海燕海娇海东海燕只从开头匹配”海.”
  海.$  海燕海娇海东海东只匹配结尾的”海.$”

* + ? { }

正则待匹配字符匹配结果说明
李.?李杰和李莲英和李二棍子李杰
李莲
李二
?表示重复零次或一次,即只匹配”李”后面一个任意字符
李.*李杰和李莲英和李二棍子李杰和李莲英和李二棍子*表示重复零次或多次,即匹配”李”后面0或多个任意字符
李.+李杰和李莲英和李二棍子李杰和李莲英和李二棍子+表示重复一次或多次,即只匹配”李”后面1个或多个任意字符
李.{1,2}李杰和李莲英和李二棍子李杰和
李莲英
李二棍
{1,2}匹配1到2次任意字符

注意:前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配

正则待匹配字符匹配结果说明
李.*?李杰和李莲英和李二棍子

惰性匹配

字符集[][^]

正则待匹配字符匹配结果说明
李[杰莲英二棍子]*李杰和李莲英和李二棍子李杰
李莲英
李二棍子
表示匹配”李”字后面[杰莲英二棍子]的字符任意次
李[^和]*李杰和李莲英和李二棍子李杰
李莲英
李二棍子
表示匹配一个不是”和”的字符任意次
[\d]456bdha34
5
6
3
表示匹配任意一个数字,匹配到4个结果
[\d]+456bdha3456
3
表示匹配任意个数字,匹配到2个结果

分组 ()与 或 |[^]

身份证号码是一个长度为15或18个字符的字符串,如果是15位则全部由数字组成,首位不能为0;如果是18位,则前17位全部是数字,末位可能是数字或x,下面我们尝试用正则来表示:

正则待匹配字符匹配
结果
说明
^[1-9]\d{13,16}[0-9x]$110101198001017032110101198001017032表示可以匹配一个正确的身份证号
^[1-9]\d{13,16}[0-9x]$11010119800101701101011980010170表示也可以匹配这串数字,但这并不是一个正确的身份证号码,它是一个16位的数字
^[1-9]\d{14}(\d{2}[0-9x])?$1101011980010170False现在不会匹配错误的身份证号了
()表示分组,将\d{2}[0-9x]分成一组,就可以整体约束他们出现的次数为0-1次
^([1-9]\d{16}[0-9x]|[1-9]\d{14})$110105199812067023110105199812067023表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}

转义符 \

在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的”\n”而不是”换行符”就需要对”\”进行转义,变成’\\’。

在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次”\n”,字符串中要写成’\\n’,那么正则里就要写成”\\\\n”,这样就太麻烦了。这个时候我们就用到了r’\n’这个概念,此时的正则是r’\\n’就可以了。

正则待匹配字符匹配结果说明
\n\n False因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配
\\n\n True转义\之后变成\\,即可匹配
“\\\\n”‘\\n’ True如果在python中,字符串中的’\’也需要转义,所以每一个字符串’\’又需要转义一次
r’\\n’r’\n’ True在字符串之前加r,让整个字符串不转义

贪婪匹配

在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配

正则待匹配字符匹配结果说明
<.*><script>…<script><script>…<script>默认为贪婪匹配模式,会匹配尽量长的字符串
<.*?>r’\d’ <script>
<script>
加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串

几个常用的非贪婪匹配Pattern

*?     重复任意次,但尽可能少重复
+?     重复1次或更多次,但尽可能少重复
??     重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}?  重复n次以上,但尽可能少重复

.*?的用法

.  是任意字符
*  是取 0 至 无限长度
?  是非贪婪模式。
合在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:
.*?x 就是取前面任意长度的字符,直到一个x出现

re模块下的常用方法

# re是regular expression的缩写,表示正则表达式
import re# findall()返回所有满足匹配条件的结果,放在列表里
ret = re.findall('a', 'eva egon yuan')  
print(ret)           #结果 : ['a', 'a']# search()函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以,通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None
ret = re.search('a', 'eva egon yuan').group()
print(ret)           #结果 'a'# match()同search,不过在字符串开始处就开始进行匹配
ret = re.match('a', 'abc').group()  
print(ret)           # 结果 'a',如果是b,则匹配不到,返回None# split()先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割,不是很常用
ret = re.split('[ab]', 'abcd')  
print(ret)           #结果 ['', '', 'cd']# re.sub() 正则替换,sub是substitude的缩写,表示替换,re.sub是正则表达式的函数,实现比普通字符串更强大的替换功能,语法如下sub(pattern,repl,string,count=0,flag=0)1))pattern正则表达式的字符串 ,eg中r'\w+',(r'',标识不转义)2))repl被替换的内容,就是替换成的内容,eg中'10'3))string就是被替换的字符串,eg中"xy 15 rt 3e,gep"4))count:由于正则表达式匹配的结果是多个,使用count来限定替换的个数从左向右,默认值是0,替换所有的匹配到的结果eg中25))flags是匹配模式,可以使用按位或者“|”表示同时生效,也可以在正则表达式字符串中flags=re.Ire.I(IGNORECASE)忽略大小写,括号内是完整的写法re.M(MULTILINE)多行模式,改变^和$的行为re.S(DOTALL)点可以匹配任意字符,包括换行符re.L(LOCALE)做本地化识别的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使用re.U(UNICODE) 使用\w \W \s \S \d \D使用取决于unicode定义的字符属性。在python3中默认使用该flagre.X(VERBOSE)冗长模式,该模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注释re.sub(r'\w+','10',"xy 15 rt 3e,gep",2,flags=re.I )     # 结果 '10 10 re 3e,gep',
# 其中r'\w+'为正则表达式,匹配多个英文单词或者数字,'10'为被替换的内容,“xy 15 rt 3e,gep”是re匹配的字符串内容,count只替换前2个,flag表示忽略大小写# subn()正则替换,返回元组(替换的结果,替换了多少次) 
ret = re.subn('\d', 'H', 'eva3egon4yuan4')
print(ret) # compile()将正则表达式编译成为一个 正则表达式对象
obj = re.compile('\d{3}')      # 规则要匹配的是3个数字 
# 正则表达式对象调用search,参数为待匹配的字符串
ret = obj.search('abc123eeee')  
print(ret.group()) #结果 123 # finditer返回一个存放匹配结果的迭代器
import re 
ret = re.finditer('\d', 'ds3sy4784a') 
print(ret)               # <callable_iterator object at 0x10195f940> 
print(next(ret).group()) # 查看第一个结果 
print(next(ret).group()) # 查看第二个结果 
print([i.group() for i in ret]) # 查看剩余的左右结果

注意:

1 findall的优先级查询:

import reret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret)  # ['oldboy'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可,用 ?:ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(ret)  # ['www.oldboy.com']

2 split的优先级查询

ret=re.split("\d+","eva3egon4yuan")
print(ret) # ['eva', 'egon', 'yuan']ret=re.split("(\d+)","eva3egon4yuan")
print(ret) # ['eva', '3', 'egon', '4', 'yuan']# 在匹配部分加上()之后所切出的结果是不同的,
# 没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
# 这个在某些需要保留匹配部分的使用过程是非常重要的。# 添加表现和匹配标签
# 可以在分组中利用?P<name>的形式给分组起名字,获取的匹配结果可以直接用group('名字')拿到对应的值
ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
print(ret.group('tag_name'))  # 结果 h1
print(ret.group())            # 结果 <h1>hello</h1># 如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致,获取的匹配结果可以直接用group(序号)拿到对应的值
ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
print(ret.group(1))
print(ret.group())           # 结果 <h1>hello</h1>

 

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

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

相关文章

mysqld_safe启动mysql

/home/data_mysql/mysql_3306/bin/mysqld_safe --defaults-file/home/data_mysql/mysql_3306/my.cnf --userroot & 原来的 /home/data_mysql/mysql_3306/bin/mysqld --defaults-file/home/data_mysql/mysql_3306/my.cnf --basedir/home/data_mysql/mysql_3306 --datadir/ho…

订阅内容解码失败(非base64码)_【火眼金睛】超强解码能力——邦纳全新ABR系列读码器来袭!...

点击关注▲ “邦纳”&#xff0c;开启智造之旅邦纳全新ABR系列读码器具有超强的解码能力&#xff0c;两种不同子系列产品&#xff0c;具有多重分辨率和镜头配置。从此读码不再是难题&#xff01;产品特点超强的解码能力使其可以读取困难的1D/2D码&#xff0c;包括DPM码和低对比…

程序员面试、算法研究、编程艺术、红黑树4大系列集锦与总结

程序员面试、算法研究、编程艺术、红黑树4大经典原创系列集锦与总结 作者&#xff1a;July--结构之法算法之道blog之博主。 时间&#xff1a;2010年10月-2011年6月。 出处&#xff1a;http://blog.csdn.net/v_JULY_v 。 声明&#xff1a;版权所有&#xff0c;侵犯必究。 前言 …

android中资源文件的两种访问方式,在android开发中进行数据存储与访问的多种方式介绍...

在android开发中进行数据存储与访问的多种方式介绍更新时间&#xff1a;2013年06月07日 16:24:23 作者&#xff1a;很多时候我们的软件需要对处理后的数据进行存储或再次访问&#xff0c;Android为数据存储提供了多种方式&#xff0c;首先给大家介绍使用文件如何对数据进行存…

MySQL5.6主从复制(读写分离)方案

MySQL5.6主从复制(读写分离)方案 https://yq.aliyun.com/articles/24255 摘要&#xff1a; 一、前言&#xff1a;为什么MySQL要做主从复制&#xff08;读写分离&#xff09;&#xff1f; 通俗来讲&#xff0c;如果对数据库的读和写都在同一个数据库服务器中操作&#xff0c;业务…

Python 内置模块之 os

os.walk os.walk() 方法是一个简单易用的文件、目录遍历器&#xff0c;可以帮助我们高效的处理文件、目录方面的事情。简单来说&#xff0c;就是挨个遍历指定路径下的目录&#xff08;文件夹&#xff09;和文件。用于通过在目录树中游走输出在目录中的目录名&#xff0c;文件名…

[arm驱动]linux内核时钟

《[arm驱动]linux内核时钟》涉及内核驱动函数四个&#xff0c;内核结构体一个&#xff0c;分析了内核驱动函数一个&#xff1b;可参考的相关应用程序模板或内核驱动模板一个&#xff0c;可参考的相关应用程序模板或内核驱动一个 一、内核定时器 意义:内核定时器是软件意义上…

企业网站 源码 服务邮箱:_公司企业邮箱购买,外贸企业邮箱用哪家服务好?

企业日常办公&#xff0c;经常会用到各种办公软件&#xff0c;而企业邮箱便是最常用的产品。公司在购买企业邮箱时需要考虑哪些方面&#xff0c;尤其是对于外贸行业的企业邮箱&#xff0c;应该如何选择呢&#xff1f;1. 安全保障公司企业邮箱购买时&#xff0c;首先要关注的就是…

微软公司等数据结构+算法面试100题2010版全部出炉

微软等公司数据结构算法面试100题2010版首次完整亮相 作者:July、2010年12月6日。 更新&#xff1a;现今&#xff0c;这100题的答案已经全部整理出来了&#xff0c;微软面试100题2010年版全部答案集锦&#xff1a;http://blog.csdn.net/v_july_v/arti…

android横竖屏切换布局闪退,Android-Activity横竖屏切换不杀死Activity 并监听横竖屏切换...

在上一篇博客&#xff0c;Android-Activity临时数据的保存&#xff0c;中讲解到&#xff0c;当发生横竖屏切换的时候&#xff0c;系统会杀死Activity并重新启动Activity系统会杀死Activity12-12 08:11:50.441 3347-3347/liudeli.activity D/TempDataActivity: onPause12-12 08:…

基于web的新闻发布系统_终极Linux系统ExTiX 19.8发布,基于深度操作系统deepin15.11...

近日&#xff0c;GNU/Linux开发人员Arne Exton发布了他的ExTiX 终极Linux系统的新版本&#xff0c;带有全新的底层和更新的组件。ExTiX Deepin 19.8基于Deepin Linux操作系统&#xff0c;更具体地说&#xff0c;ExTiX Deepin 19.8基于最新的Deepin 15.11版本&#xff0c;它增加…

Python 之内置函数和匿名函数

内置函数 截止到python3.6.2&#xff0c;python一共为我们提供了68个内置函数。它们就是python提供可以直接拿来使用的所有函数 Built-in Functions abs()dict()help()min()setattr()all()dir()hex()next()slice()any()divmod()id()object()sorted()ascii()enumerate()input(…

个人作业1

Deadline&#xff1a; 2017-9-30 10:00PM&#xff0c;以博客发表日期为准。 评分基准: 按时交 - 有分&#xff08;满分10分&#xff09;&#xff0c;检查的项目包括后文的三个方面 按题目要求完成个人博客注册、码云账号注册&#xff08;1分&#xff09;完成阅读作业和提问&…

“西邮漫记”--自由照耀中国

"西邮漫记"&#xff0d;&#xff0d;自由照耀中国九月初在北京linuxWorld大会上我遇见了久违的陈莉君教授&#xff0c;陈教授是西安邮电学院计算机系教授Linux内核的老师&#xff0c;上次相识是在广州参加广东Linux推进中心举办的“Linux文化节”&#xff0c;当时陈教…

numpy 是否为零_如果不懂 numpy,请别说自己是 python 程序员

(给Python开发者加星标&#xff0c;提升Python技能)作者&#xff1a;牧马人 (本文来自作者投稿)0. 前言大约七八年前&#xff0c;我曾经用 pyOpenGL 画过地球磁层顶的三维模型&#xff0c;这段代码至今仍然还运行在某科研机构里。在那之前&#xff0c;我一直觉得自己是一个合(y…

Python 第三方模块之 ElementTree(ET)- 解析XML文件

ElementTree是Python常用的处理XML文件的类。下面将介绍使用ElementTree解析、查找、修改XML的方法。 1、引用方法 import xml.etree.ElementTree as ET 2、一个XML例子 下面所有的操作都将下面这段XML为例&#xff0c;我们将它保存为sample.xml。 <?xml version"…

android 编译luajit,Android 嵌入 LuaJIT 的曲折道路

相关链接&#xff1a;Windows 下编译 LuaJIT懒人与伸手党可以直接看最底部。为什么使用 LuaJITLua 官方版的编译嵌入相对简单&#xff0c;但是为什么要用 LuaJIT 呢&#xff1f;我所了解到的优势有&#xff1a;更高的运行效率。支持运行 Lua 编译后的机器码。虽然 Lua 也支持编…

运维自动化之使用PHP+MYSQL+SHELL打造私有监控系统(一)

前言 记得刚来这家公司的时候&#xff0c;我部门就我一个运维工程师&#xff0c;然后就是经理&#xff0c;刚开始公司平台什么监控都没有&#xff0c;在我与经理的努力下&#xff0c;先搭建nagioscacti监控平台&#xff0c;后来随着公司业务的增加&#xff0c;平台的功能与服务…

面试风云录(01) - 怎样回答这两个问题?

由于工作经历的缘故&#xff0c;使我有一些面试别人的机会&#xff0c;所以应该还有一些经验可以跟大家聊聊。 当我们提到“面试” 这个词&#xff0c;总是让人有种阶级感&#xff0c;好像面试官就是高高在上&#xff0c;而面试者则是屈居于下&#xff0c;其实并非如此&#xf…

Redis Python

Python操作Redis 安装Python使用Redis的库 sudo pip install redis or sudo easy_install redis or 源码安装 详见&#xff1a;https://github.com/WoLpH/redis-py 1.1 操作模式 redis-py提供两个类Redis和StrictRedis用于实现Redis的命令&#xff0c;StrictRedis用于实现大…