Python正则表达式急速入门(小结)


Posted in Python onDecember 16, 2019

正则表达式在程序开发中会经常用到,比如数据(格式)验证、替换字符内容以及提取字符串内容等等情况都会用到,但是目前许多开发人员对于正则表达式只是处于了解或者是基本会用的阶段。一旦遇到大批量使用正则表达式的情况(例如网络爬虫)可以说基本上就抓瞎了。这篇文章我将带领大家利用 Python 来学习一下正则表达式。在阅读这篇文章前你需要掌握 Python 基础知识,或者具有其他开发语言的基础知识也可以,因为基本上每种语言使用正则表达式的方式都是类似的。

零、正则表达式基础

1.提取字符(串) 有时我们需要从一个字符串中获取一段内容,这段内容可能是一个字符也可能是一段字符串,如果用逐字对比遍历的话不仅耗时耗力而且还容易出错。那么这个时候我们就可以用到正则表达式中的 字符匹配 功能。正则表达式为我们提供了 4 种字符匹配的方法,见下表:

语法 说明 例子 可匹配字符串
. 匹配除了换行符 “\n” 以外的任意字符 a.b acb、adb、a2b、a~b
\ 转义,将转移字符后面的一个字符改变原来的意思 a[b\.\\]c abc、a.c、a\c
[] 匹配括号内的任意字符 a[b,c,d,e]f abd、acf、adf、aef
[^] 除了括号内的字符外,其他的字符都匹配 aa,b,c,d,ef a1f、a#f、azf、agf

2.预定义字符 所谓预定义字符就是正则表达式中为我们预留的专门用来匹配格式化内容的字符,例如匹配数字用的 \d 和匹配空白符的 \s 等等。我们可以利用预定义字符快速的匹配出一个字符串中符合要求的内容。预定义字符匹配的内容,同样也可以利用前面所讲的字符匹配的方式匹配出来,但是代码量会相对来说多一点。下表所列的就是预定义字符:

语法 说明 例子 可匹配字符串
^ 以什么字符串开始 ^123 123abc、123321、123zxc
$ 以什么字符串结尾 123$ abc123、321123、zxc123
\b 匹配单词边界,不匹配任何字符 \basd\b asd
\d 匹配数字0-9 zx\dc zx1c、zx2c、zx5c
\D 匹配非数字 zx\Dc zxvc、zx$c、zx&c
\s 匹配空白符 zx\sc zx c
\S 匹配非空白符 zx\Sc zxac、zx1c、zxtc
\w 匹配字母、数字和下划线 zx\wc zxdc、zx1c、zx_c
\W 匹配非字母、数字和下划线 zx\Wc zx c、zx$c、zx(c

在预定义字符中有如下几点需要注意:

  • \b 匹配的只是一个位置,这个位置的一侧是构成单词的字符,另一侧为非单词字符、字符串的开始或结束位置。\b 是零宽度。
  • \w 在不同编码语言中匹配的范围是不一样的,在使用 ASCII 码的语言中匹配的是 [a-zA-Z0-9] ,而在使用 Unicode 码的语言中匹配的是 [a-zA-Z0-9] 和汉字、全角符号等特殊字符。

3.限制数量 在某些情况下我们需要匹配重复的内容,这时我们可以使用 数量限定 模式来进行操作。数量限定如下表: 

语法 说明 例子 可匹配字符串
* 匹配0到多次 zxc* zx、zxccccc
+ 匹配1次到多次 zxc+ zxc、zxccccc
? 匹配0次或1次 zxc? zxc、zx
{m} 匹配m次 zxc{3}vb zxcccvb
{m,} 匹配m次或多次 zxc{3,}vb zxcccvb、zxccccccccvb
{,n} 匹配0次到n次 zxc{,3}vb zxvb、zxcvb、zxccvb、zxcccvb
{m,n} 匹配m次到n次 zxc{1,3} zxcvb、zxccvb、zxcccvb

4.断言 断言,又称零宽断言,指的是当断言表达式为 True 时才进行匹配,但是并不匹配断言表达式内容。和 ^ 代表开头, $ 代表结尾, \b 代表单词边界一样,先行断言和后行断言也有类似的作用,它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为零宽。所谓位置,是指字符串中第一个字符的左边、最后一个字符的右边以及相邻字符的中间。零宽断言表达式有四种:

  • 零宽度负回顾后发断言 (?<!exp),表达式不成立时匹配断言后面的位置,成立时不匹配。例如 \w+(?<zxc)\d,匹配不以 zxc 结尾的字符串;
  • 零宽度负回顾先行断言 (?!exp),表达式匹配断言前面的位置,成立时则不匹配。例如:\d(?!zxc)\w+,匹配不以 zxc 开头的字符串;
  • 先行断言 (?=exp),断言为真时匹配断言前面的位置,例如要在 “a regular expression” 这个字符串中追匹配出 regular 中的 re ,我们可以这么写 re(?=gular);
  • 后发断言 (?<=exp),断言为真时匹配断言后面的位置,例如对 “egex represents regular expression” 这个字符串要想匹配除 regex 和 regular 之外的re,可以用 re(?!g),该表达式限定了re右边的位置,这个位置后面不是字符g。先行和后发的区别就在于该位置之后的字符能否匹配括号中的表达式。

5.贪婪/非贪婪 正则表达式会尽可能多的去匹配字符,这被称为贪婪模式,贪婪模式是正则表达式默认的模式。但是有时候贪婪模式会给我们造成不必要的困扰,例如我们要匹配字符串 “Jack123Chen123Chen” 中的 “Jack123Chen”,但是贪婪模式匹配出的却是 “Jack123Chen123Chen”,这时我们就需要用到非贪婪模式来解决这个问题,非贪婪模式常用的表达式如下: 

语法 说明
*? 匹配0次或多次,但要尽可能少重复
+? 匹配1次或多次,但要尽可能少重复
?? 匹配0次或1次,但要尽可能少重复
{m,}? 匹配m次或多次,但要尽可能少重复
{m,n}? 匹配m次或n次,但要尽可能少重复

6.其他 上述内容在正则表达式中都是常用的,下面我们再来看看不常用到的,但是功能同样强大的语法。

  • OR 匹配又称匹配分支,也就是说只要有一个分支匹配就算匹配,这和我们在开发中使用的 OR 语句类似。OR 匹配利用 | 分割分支,例如我们需要匹配出英文姓名,但是在英文中姓和名中间有可能是以 · 分割,也有可能是以空格分隔,这时我们就可以利用 OR 匹配来处理这个问题。格式如下:[A-Za-z]+·[A-Za-z]+|[A-Za-z]+\s[A-Za-z]+
  • 组合,将几个项组合为一个单元,这个单元可通过* + ? | 等符号加以修饰,而且可以记住和这个组合相匹配的字符串以提供伺候的引用使用。分组使用 () 来表示。例如获取日期的正则表达式可以这么写:\d{4}-(0[1-9]|1[0-2])-(0[1-9]|12|3[01])。第一个分组 (0[1-9]|1[0-2]) 代表月的正则匹配,第二个分组 (0[1-9]|12|3[01]) 代表日的正则匹配。

一、Python 使用正则表达式

在 Python 中使用正则表达式很简单,re 模块向我们提供了正则表达式的支持。使用步骤一共三步:

  • 将正则表达式字符串转换为 Pattern 的实例;
  • 使用 Pattern 实例去处理要匹配的字符,匹配结果是一个 Match 实例;
  • 利用 Match 实例去进行之后的操作。

在 Python 中我们常用的 re 的方法有六种,分别是: compile 、 match 、 search 、 findall 、 split 和 sub ,下面就针对这六种方法进行一下讲解。

compile compile 方法的作用是将正则表达式字符串转化为 Pattern 实例,它具有两个参数 pattern 和 flags ,pattern 参数类型是 string 类型,接收的是正则表达式字符串,flags 类型是 int 类型,接收的是匹配模式的编号,flags 参数是非必填项,默认值为 0 (忽略大小写)。flags 匹配模式有如下 6 种: 

匹配模式 说明
re.I 忽略大小写
re.M 多行匹配模式
re.S 任意匹配模式
re.L 预定义字符匹配模式
re.U 限定字符匹配模式
re.V 详细模式

上述六种模式在实际开发中很少用到,我们只需要了解即可。 使用 compile 很简单,如下: 

import re ​ 
pattern = re.compile(r'\d')

2.match match 的作用是利用 Pattern 实例,从字符串左侧开始匹配,如果匹配到就返回一个 Match 实例,如果没有匹配到就返回 None。

import re ​ 
def getMatch(message): 
  pattern = re.compile(r'(\d{4}[-年])(\d{2}[-月])(\d{2}日{0,1})') 
  match = re.match(pattern, message) 
  if match: 
    print(match.groups()) 
    for item in match.groups(): 
      print(item) 
  else: 
    print("没匹配上") ​ 
​ 
if __name__ == '__main__': 
  message = "2019年01月23日大会开始" 
  getMatch(message) 
  message = "会议于2019-01-23召开" 
  getMatch(message)

在代码中我们使用了 groups 方法,这个方法用来获取匹配出来的字符串组。到这里过一会有很多读者感到纳闷,为什么第一段内容能匹配出来年月日,而第二段内容不能呢?这是因为 match 方法是从字符串的起始位置匹配的。 代码运行结果如图:

Python正则表达式急速入门(小结)

3.search search 方法与 match 方法功能是一样的,只不过 search 方法是对整个字符串进行匹配。将前一小节代码中的 getMatch 方法进行改动,即可将第二段内容中的年月日匹配出来。

import re ​ 
def getMatch(message): 
  pattern = re.compile(r'(\d{4}[-年])(\d{2}[-月])(\d{2}日{0,1})') 
  match = re.search(pattern, message) 
  if match: 
    print(match.groups()) 
    for item in match.groups(): 
      print(item) 
  else: 
    print("没匹配上") ​ 
​ 
if __name__ == '__main__': 
  message = "2019年01月23日大会开始" 
  getMatch(message) 
  message = "会议于2019-01-23召开" 
  getMatch(message)

上述代码运行结果如下图:

Python正则表达式急速入门(小结)

4.findall findall 方法的作用是匹配整个字符串,以列表的形式返回所有匹配结果。

import re ​ 
​ 
def getMatch(message): 
  pattern = re.compile(r'\w+') 
  match = re.findall(pattern, message) 
  if match: 
    print(match) 
  else: 
    print("没匹配上") ​ 
​ 
if __name__ == '__main__': 
  message = "my name is 张三" 
  getMatch(message) 
  message = "张三 is me" 
  getMatch(message)

代码运行结果如下图:

Python正则表达式急速入门(小结)

5.split split 方法是利用指定的字符来分割字符串。

import re ​ 
​ 
def getMatch(message): 
  pattern = re.compile(r'-') 
  match = re.split(pattern, message) 
  if match: 
    print(match) 
  else: 
    print("没匹配上") ​ 
​ 
if __name__ == '__main__': 
  message = "2018-9-12" 
  getMatch(message) 
  message = "第一步-第二步-第三步-第四步-and more" 
  getMatch(message)

上述代码运行结果如下图:

Python正则表达式急速入门(小结)

6.sub sub 方法用来替换字符串,它接受5个参数,其中常用的有三个:

  • pattern,Pattern 实例
  • string,等待替换的字符串
  • repl,表示替换的新字符串或需要执行的替换方法
  • count,替换次数,默认为0表示全部替换
import re ​ 
​ 
def getMatch(match): 
  return match.group(0).replace(r'年龄', 'age') ​ 
​ 
if __name__ == '__main__': 
  message = "your 年龄 ?" 
  pattern=re.compile(r'\w+') 
  print(re.sub(pattern,getMatch,message))

代码运行结果如下图:

Python正则表达式急速入门(小结)

三、总结

Python 中正则表达式使用起来非常方便,上面所展示的代码,完全可以直接复制出来稍加修改后放在项目中使用。内容不多,主要是讲解代码怎么使用,希望大家完全理解掌握了正则表达式的写法。

作者简介:
朱钢,笔名喵叔,国内某技术博客认证专家,.NET高级开发工程师,7年一线开发经验,参与过电子政务系统和AI客服系统的开发,以及互联网招聘网站的架构设计,目前就职于一家初创公司,从事企业级安全监控系统的开发。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python爬虫爬验证码实现功能详解
Apr 14 Python
Python安装使用命令行交互模块pexpect的基础教程
May 12 Python
Python 遍历子文件和所有子文件夹的代码实例
Dec 21 Python
python如何修改装饰器中参数
Mar 20 Python
Pyqt实现无边框窗口拖动以及窗口大小改变
Apr 19 Python
在Python 不同级目录之间模块的调用方法
Jan 19 Python
python 使用socket传输图片视频等文件的实现方式
Aug 07 Python
从numpy数组中取出满足条件的元素示例
Nov 26 Python
Pytorch Tensor 输出为txt和mat格式方式
Jan 03 Python
django 解决自定义序列化返回处理数据为null的问题
May 20 Python
Pytorch通过保存为ONNX模型转TensorRT5的实现
May 25 Python
手把手教你将Flask应用封装成Docker服务的实现
Aug 19 Python
如何基于Python制作有道翻译小工具
Dec 16 #Python
django框架单表操作之增删改实例分析
Dec 16 #Python
Python生成个性签名图片获取GUI过程解析
Dec 16 #Python
Python列表切片常用操作实例解析
Dec 16 #Python
python之pymysql模块简单应用示例代码
Dec 16 #Python
python装饰器使用实例详解
Dec 14 #Python
python函数不定长参数使用方法解析
Dec 14 #Python
You might like
ThinkPHP中自定义错误页面和提示页面实例
2014/11/22 PHP
微信公众号判断用户是否已关注php代码解析
2016/06/24 PHP
PHP的mysqli_stmt_init()函数讲解
2019/01/24 PHP
模仿JQuery.extend函数扩展自己对象的js代码
2009/12/09 Javascript
Javascript实现页面跳转的几种方式分享
2013/10/26 Javascript
js获取对象为null的解决方法
2013/11/21 Javascript
jquery图片轮播插件仿支付宝2013版全屏图片幻灯片
2014/04/03 Javascript
JSON+Jquery省市区三级联动
2016/01/13 Javascript
如何让一个json文件显示在表格里【实现代码】
2016/05/09 Javascript
jQuery调用Webservice传递json数组的方法
2016/08/06 Javascript
js获取页面引用的css样式表中的属性值方法(推荐)
2016/08/19 Javascript
基于Vue的文字跑马灯组件(npm 组件包)
2017/05/24 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(下)
2018/04/18 Javascript
vue实现购物车抛物线小球动画效果的方法详解
2019/02/13 Javascript
javascript刷新父页面方法汇总详解
2019/10/10 Javascript
Layui实现主窗口和Iframe层参数传递
2019/11/14 Javascript
JavaScript利用键盘码控制div移动
2020/03/19 Javascript
[01:32]寻找你心中的那团火 DOTA2 TI9火焰传递活动今日开启
2019/05/16 DOTA
Python使用cx_Oracle模块将oracle中数据导出到csv文件的方法
2015/05/16 Python
python获取文件路径、文件名、后缀名的实例
2018/04/23 Python
使用Anaconda3建立虚拟独立的python2.7环境方法
2018/06/11 Python
解决Django生产环境无法加载静态文件问题的解决
2019/04/23 Python
Python实现操纵控制windows注册表的方法分析
2019/05/24 Python
简单了解python gevent 协程使用及作用
2019/07/22 Python
Python实现搜索算法的实例代码
2020/01/02 Python
PyQt使用QPropertyAnimation开发简单动画
2020/04/02 Python
世界最大的私人旅行指南出版商:孤独星球
2016/08/23 全球购物
KIKO美国官网:意大利的平价彩妆品牌
2017/05/16 全球购物
房地产还款计划书
2014/01/10 职场文书
乔迁之喜主持词
2014/03/27 职场文书
超市活动计划书
2014/04/24 职场文书
捐书活动总结
2014/05/04 职场文书
乡镇法制宣传日活动总结
2015/05/05 职场文书
党员发展大会主持词
2015/07/03 职场文书
Requests什么的通通爬不了的Python超强反爬虫方案!
2021/05/20 Python
Win2008系统搭建DHCP服务器
2022/06/25 Servers