前言

输入一个手机号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] 8 True 在一个字符组里枚举合法的所有字符,字符组里的任意一个字符
和”待匹配字符”相同都视为可以匹配
[0123456789] a False 由于字符组中没有”a”字符,所以不能匹配
[0-9] 7 True 也可以用-表示范围,[0-9]就和[0123456789]是一个意思
[a-z] s True 同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示
[A-Z] B True [A-Z]就表示所有的大写字母
[0-9a-fA-F] e True 可以匹配数字,大小写形式的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] 456bdha3 4
5
6
3
表示匹配任意一个数字,匹配到4个结果
[\d]+ 456bdha3 456
3
表示匹配任意个数字,匹配到2个结果

分组 ()与 或 |[^]

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

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

Python 内置模块之 re相关推荐

  1. python turtle循环图案-Python内置模块turtle绘图详解

    urtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x.纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数指令的控制,在这个平面坐标系中移动,从而在它爬行的 ...

  2. python内置模块_三分钟读懂Python内置模块collections

    collections模块 Python内置模块,在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.d ...

  3. python config模块_用Python内置模块处理ini配置文件

    原标题:用Python内置模块处理ini配置文件 简介 开发人员每天都在处理一些大型而复杂的项目, 而配置文件会帮到我们并节省不少时间.在处理配置文件过程中,无需更改源代码本身,只需要调整配置文件即可 ...

  4. python内置模块(三)

    ----------------------------接 python内置模块(二)--------------------------- 八. shelve模块      shelve模块是一个简 ...

  5. python内置模块re_python内置模块[re]

    python内置模块[re] re模块: python的re模块(Regular Expression正则表达式)提供各种正则表达式的匹配操作,在文本解析.复杂字符串分析和信息提取时是一个非常有用的工 ...

  6. Python——内置模块中的内置函数

    内置模块中的内置函数 我们在安装好了 Python 配置文件后,也将 Python 本身带有的库也安装好了,Python 自带的库也叫做 Python的内置模块. Python 的内置模块是 Pyth ...

  7. python内置模块和内置方法

    python内置模块 time json re logging random os sys xml pikle shelve getopt uuid subprocess collections fu ...

  8. Python 内置模块之 re 库,一文搞定正则表达式初阶用法,滚雪球学 Python 第 13 篇

    橡皮擦,一个逗趣的互联网高级网虫.新的系列,让我们一起 Be More Pythonic. 滚雪球学 Python 第二轮 已完成的文章清单 十三.Python 内置模块之 re 库,一文搞定正则表达 ...

  9. python内置模块重要程度排名_论Python常见的内置模块

    Python常见的内置模块 系统的内置模块 sys hashlib hmac base64 time datetime sys模块 sys.argv()# 在Python脚本传参使用 sys.exit ...

  10. python常用内置模块-Python内置模块和第三方模块

    Python的强大之处在于他有非常丰富和强大的标准库和第三方库(模块),几乎你想实现的任何功能都有相应的Python库支持,就类似于C#中的类库亦或JAVA的jar包,前端中的JS库. 使用模块有什么 ...

最新文章

  1. Oracle 12C -- 清空audit记录
  2. CCNA实验之---单臂路由实现VLAN间路由
  3. Mac安装php和redis扩展
  4. Linux脚本双引号字符去除,shell命令去除字符串里双引号
  5. 数据库存入表情符报错问题
  6. Android Dialog的简单说明
  7. python 中gcd用法_Python中while语句的基本用法不了解一下嘛?
  8. VPP教程 基本命令 记录
  9. goEasy的简单使用
  10. 市场研究中的数据分析知识整理 (四)-主成分分析和因子分析
  11. Layui的下拉框样式失效问题
  12. Java验证邮箱格式是否正确
  13. echarts节点折叠实现
  14. 亲情友情爱情:《悲惨世界》第四部《卜吕梅街的柔情和圣德尼街的史诗》/人性:《悲惨世界》第五部《冉阿让》摘录...
  15. matlab定步长ode,[转载]matlab ode45 函数传自定义参数用法及定步长ode
  16. Linux共享打印机手机打印,[分享]让linux和linux之间共享打印机
  17. 二分图判断以及二分图最大匹配
  18. Java垃圾回收与算法
  19. 1.可编程并行接口实验
  20. 学堂在线-程序设计基础-第四章

热门文章

  1. 项目经理如何把工作简单化
  2. vue 各组件 使用 Demo
  3. FastJson 中 jsonArray 转换成 list 集合的方法
  4. easyUI 日期控件修改...
  5. 牛客网——最简真分数
  6. vue项目中axios的封装
  7. JavaScript - 动态数据
  8. 如何脱离SDK,使用DW5.5和phonegap以及JQMobile搭建开发环境
  9. Phaser开源2d引擎 javascript/html5游戏框架
  10. CentOS-6.3安装使用MongoDB