python中提供了re这个模块提供对正则表达式的支持。

一、正则表达式常用到的一些语法(并非全部):

. 匹配任意单个字符
[...] 匹配单个字符集
\w 匹配单词字符,即[a-zA-Z0-9]
\W 匹配非单词字符集,例如 ‘*’
\d 匹配数字,即[0-9]
\D 匹配非数字
\s 匹配空白字符
\S 匹配非空白字符
* 匹配前一个字符0次或者任意多次
+ 匹配前一个字符1次或者任意多次
? 匹配前一个字符0次或者1次
{m} 匹配前一个字符m次
{m,n} 匹配前一个字符最少m次,最多n次
*? 非贪婪模式匹配前一个字符0次或者任意多次
+? 非贪婪模式匹配前一个字符1次或者任意多次
?? 非贪婪模式匹配前一个字符0次或者1次
{m,n}? 非贪婪模式匹配前一个字符最少m次,最多n次
^ 匹配字符串开头
$ 匹配字符串结尾
\A 制定的字符串匹配必须出现在开头
\Z 制定的字符串匹配必须出现在结尾
| 匹配左右任意一个表达式,相当于“或”的含义
() 匹配一个分组,括号中为该分组所需匹配的内容
\<number> 引用匹配编号为<number>的分组中的字符串
(?P<group_name>) 为匹配分组制定特定的组名
(?P=<group_name>) 引用特定组名的匹配字符串

几点解释:

1. 两种方式都可以进行匹配:

(1)首先创建pattern,然后进行match

  1. pa = re.compile(r'[\w]{6}') # 首先利用re模块创建一个pattern实例pa
  2. ma = pa.match('string') # 利用这一pattern对正则表达式进行匹配
  3. ma.group() #打印匹配的内容,输出为'string'

(2)直接利用re模块中的函数match进行匹配

  1. ma = re.match(r'[\w]{6}', string’)
  2. print(ma.group()) # 打印匹配的内容,输出为'string'

2. 贪婪模式和非贪婪模式:

贪婪模式:总是尝试匹配尽可能多的字符;

非贪婪模式:总是尝试匹配尽可能少的字符。

例如:利用正则表达式‘python*’匹配‘pythonnnnnpython’,此时ma = re.match(r'python*',‘pythonnnpython’),得到的ma.group()为‘pythonnn’;利用‘python*?’进行匹配,此时ma = re.match(r'python*?',‘pythonnnpython’),得到的ma.group()为‘python’。

3. 关于逻辑与分组语法的用法:

| 匹配左右任意一个表达式,相当于“或”的含义
() 匹配一个分组,括号中为该分组所需匹配的内容
\<number> 引用匹配编号为<number>的分组中的字符串
(?P<group_name>) 为匹配分组制定特定的组名
(?P=<group_name>) 引用特定组名的匹配字符串

首先,|和()的用法比较容易理解,例如我们需要匹配多个邮箱的地址是否合法,例如有gmail邮箱、outlook邮箱,假定@前的字符数为6到20个,此时可以写成:

  1. >>> pa = re.compile('[\w]{6,20}@(gmail|outlook).com$')
  2. >>> ma = pa.match('bokeyuan@gmail.com')
  3. >>> ma.group()
  4. 'bokeyuan@gmail.com'
  5. >>> ma = pa.match('bokeyuan@outlook.com')
  6. >>> ma.group()
  7. 'bokeyuan@outlookl.com'

后边三个的用法根据下边的例子进行说明:

  1. >>> str = '<code>python</code>'
  2. >>> ma = re.match(r'<[\w]+>', str)
  3. >>> ma.group()
  4. '<code>'
  5. >>> ma = re.match(r'<([\w]+>)[\w]+</\1', str)
  6. >>> ma.group()
  7. '<code>python</code>'
  8. >>> ma = re.match(r'<(?P<group1>[\w]+>)[\w]+</(?P=group1)', str)
  9. >>> ma.group()
  10. '<code>python</code>'

其中,第一个例子就是对字符串‘<code>'进行匹配。我们发现str中其实有两部分是完全相同的,就是都含有'code>'这个substring,于是可以看第二个例子,我们用()将([\w]+>)这部分内容括住时,这部分匹配的字符串就是'code>',([\w]+>)就是一个分组,没有起名字的情况下默认<number>为1,因此在我们需要在末尾再次引用到它的时候,就写上 /1 即可。第三个例子与第二个例子的效果完全相同,只不过为了更加清楚的记住匹配分组的名字,我们利用(?P<group_name>)这一语法功能,人为的为这个分组取了一个group1的名字,在最后又引用了这一分组。

4. 注意字符串中转义字符的问题

上述例子中,出现在正则表达式前边的r是原始字符串操作符,可以写为r或者R:表示字符串内的所有字符都按原始意思解释。

例如:‘c:\python\test.py’ 如果不加r,则计算机会将 \t 会变成转义字符解释;加上r以后,写为:r‘c:\python\test.py’,计算机就会直接输出c:\python\test.py,否则要想输出c:\python\test.py,必须将字符串写为‘c:\\python\\test.py’

二、介绍几个re模块中的常用函数

1. search(pattern, string, flags=0)函数

search函数功能:在字符串中查找匹配

例如:博客会记录来访者的数量,我们通过正则匹配查找字符串中的数字:

  1. str1 = 'number of visitors = 1000'
  2. info = re.search(r'\d+', str1) # 匹配字符串str1中的数字
  3. print('访客数量:', info)
  4. print(info.group()) # 显示匹配的内容

当然,上述操作也可以通过对字符串直接操作获得,例如:print('访客数量:', str1.find('1000')) 。但是这样存在一个问题,因为访客数量实在不断变化的,一旦1000这个数字增加,用字符串操作就难以实现。但是利用search函数就不存在这样的问题。

2. findall(pattern, string, flags=0)函数

findall函数功能:找到匹配,并返回所有匹配内容的列表

例如,博客记录了最近三天每天的访客记录,我们需要将三天的访客数量都查找出来,并计算总的访客数量,此时用search函数无法直接将三天的访客数量同时提取,可以采用findall函数:

  1. str2 = 'day1=22, day2=34, day3=13'
  2. info = re.findall(r'=[\d]+', str2)
  3. print(info)
  4. print('三天的访客数量为:', sum([int(x[1:]) for x in info]))

3. sub(pattern, repl, string, count=0, flags=0)函数

sub函数功能:将字符串中匹配正则表达式的部分替换为其他值。其中repl可以是一个字符串,也可以是一个函数。

当repl是一个字符串时,仍然以访客记录为例,当增加一个访客时,需要修改记录中的数字:

  1. str3 = 'number of visitors = 1000'
  2. info = re.sub(r'[\d]+', '', str3)
  3. print(info) # 此时输出结果为 number of visitors = 1001

但是此时每次修改都必须手动输入数字,显然,对于这种随时变化的数字来说,这种操作是不合理的。而sub函数的高明之处就是允许repl是一个函数。

当repl为一个函数时,首先会在string中查找pattern的匹配,查找到的匹配是一个match对象,这个match对象就会被传递到repl这个函数中。上述例子可以这样实现:

  1. # 首先,定义一个增加访客数量的函数,函数的参数是一个match对象
  2. def add_num(match):
  3. val = match.group()
  4. num = int(val) + 1
  5. return str(num)
  6.  
  7. str3 = 'number of visitors = 1000'
  8. print('最新访客数量:', re.sub(r'[\d]+', add_num, str3)) # 打印结果,最新访客数量:number of visitors = 1001

4. split(pattern, string, maxsplit=0, flags=0)函数

split函数功能:根据匹配分割字符串,返回分割字符串组成的列表

  1. str4 = 'day1=22, day2=34, day3=13'
  2. print(re.split(r', ', str4)) # 打印出的内容为 ['day1=22', 'day2=34', 'day3=13']

以上就是正则表达式的一些学习笔记,并不十分完全,欢迎大家交流。

python学习笔记(一)——关于正则表达式的学习小结的更多相关文章

  1. 【学习笔记】JavaScript的基础学习

    [学习笔记]JavaScript的基础学习 一 变量 1 变量命名规则 Camel 标记法 首字母是小写的,接下来的字母都以大写字符开头.例如: var myTestValue = 0, mySeco ...

  2. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  3. 20145213《Java程序设计学习笔记》第六周学习总结

    20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...

  4. Hadoop学习笔记(10) ——搭建源码学习环境

    Hadoop学习笔记(10) ——搭建源码学习环境 上一章中,我们对整个hadoop的目录及源码目录有了一个初步的了解,接下来计划深入学习一下这头神象作品了.但是看代码用什么,难不成gedit?,单步 ...

  5. 20145230《java学习笔记》第七周学习总结

    20145230 <Java程序设计>第7周学习总结 教材学习内容 Lambda语法概览 我们在许多地方都会有按字符串长度排序的需求,如果在同一个方法内,我们可以使用一个byName局部变 ...

  6. 【学习笔记】jQuery的基础学习

    [学习笔记]jQuery的基础学习 新建 模板 小书匠  什么是jQuery对象? jQuery 对象就是通过jQuery包装DOM对象后产生的对象.jQuery 对象是 jQuery 独有的. 如果 ...

  7. 吴裕雄--天生自然python学习笔记:Python3 正则表达式

    Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re 模块使 Python 语言拥有全部的正则表达式功能. compile 函数根据一个模式字符串和可选的标志参 ...

  8. Python机器学习笔记:sklearn库的学习

    网上有很多关于sklearn的学习教程,大部分都是简单的讲清楚某一方面,其实最好的教程就是官方文档. 官方文档地址:https://scikit-learn.org/stable/ (可是官方文档非常 ...

  9. 学习笔记TF045:人工智能、深度学习、TensorFlow、比赛、公司

    人工智能,用计算机实现人类智能.机器通过大量训练数据训练,程序不断自我学习.修正训练模型.模型本质,一堆参数,描述业务特点.机器学习和深度学习(结合深度神经网络). 传统计算机器下棋,贪婪算法,Alp ...

  10. .NET学习笔记(1)— C#学习路线图

    目录 一:引言 二:.NET技术体系 三:常用工具汇总 四:学习资源汇总 五:书籍推荐 六:关于阅读技术书籍的经验 七:总结   一:引言 因为工作调整,从PHP开发零基础转型到.NET开发,前期没有 ...

随机推荐

  1. bzoj 3727: Final Zadanie 思维题

    题目: Description 吉丽YY了一道神题,题面是这样的: "一棵n个点的树,每条边长度为1,第i个结点居住着a[i]个人.假设在i结点举行会议,所有人都从原住址沿着最短路径来到i结 ...

  2. Codeforces Round #402 (Div. 2) 阵亡记

    好长时间没有打Codeforces了,今天被ysf拉过去打了一场. lrd也来参(nian)加(ya)比(zhong)赛(sheng) Problem A: 我去,这不SB题吗.. 用桶统计一下每个数 ...

  3. jquery鼠标悬停事件hover()

    在JQuery中提供了.hover()事件,hover的第一个参数(匿名方法)表示mouseenter,第二个参数表示mouseleave,即表示可以为hover传递两个参数.如下代码所示: $( & ...

  4. python编程范式培训文档,主要是结合4种代码和,对oop和面向过程编程区别和oop转化公式培训。

    这是写得培训文档.代码例子在附件. 是经过深入考察 4个git项目里面,找出代码非常非常十分low.代码重复得吓人的的最本质原因.提炼出oop转化公式. 围绕附件中的4种代码写法思维来实现同一个任务, ...

  5. 用户认证auth模块

    一.auth模块 from django.contrib import auth 1 .authenticate()   :验证用户输入的用户名和密码是否相同 提供了用户认证,即验证用户名以及密码是否 ...

  6. T-SQL 高级编程

    在Sql Server 中访问数据库一般有2种方式: 1.一种是使用应用程序编程接口API 2.数据库语句 变量:局部变量:以@为前缀,如@Age:全局变量以@@为前缀:(Ps:全局变量以系统定义和维 ...

  7. VS 关于无法打开项目文件,此安装不支持该项目类型的问题

    用VS打开后有时会出现类似: 无法打开项目文件,此安装不支持该项目类型 的错误,这个错误一般都是由于用低版本VS打开高版本项目文件造成的 其中包括: 1.用VS2003 打开包括VS2005以上版本项 ...

  8. 关于ArcGis for javascrept之Map类

    ArcGis for javascrept_ESRI_Map类:  1. 构造方法:esri.Map(); 参数: extent 如果设置了该选项,一旦这个选项的投影被设置,那么所有的图层都在定义的投 ...

  9. PHP和MySql数据库,如何获取每个分类的记录的总数

    示例的数据库,如下: 本文说的问题,就是统计每个学院(Sdept)的人数. 还有很多情况,比如说:在制作CMS的时候,文章有个分类问题,所有的文章的记录都是存放到同一个表中. 当我们需要统计每个分类的 ...

  10. [原创]SQL表值函数:返回自定义时间段的日期数据

    跟以往类似,我依旧介绍一个我日常开发遇到的知识点,谨此记录一下,也希望能帮助到一些朋友. 这次我要介绍的是通过SQL函数返回你输入的两个时间点内的日期数据. 效果图如下: 执行函数:SELECT * ...