1. 模式匹配与正则表达式笔记(第7章)(代码下载)

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

1.1 正则表达式匹配步骤
虽然在Python 中使用正则表达式有几个步骤,但每一步都相当简单。

  1. 用import re 导入正则表达式模块。
  2. 用re.compile()函数创建一个Regex 对象(记得使用原始字符串)。
  3. 向Regex 对象的search()方法传入想查找的字符串。它返回一个Match 对象。
  4. 调用Match 对象的group()方法,返回实际匹配文本的字符。
  1. # 用import re 导入正则表达式模块
  2. import re
  3. # 创建了一个Regex对象
  4. phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
  5. # 匹配字符串
  6. mo = phoneNumRegex.search('My number is 415-555-4242.')
  7. # group()方法返回实际匹配的字符串
  8. print('phone num found is: ' + mo.group())
  1. phone num found is: 415-555-4242

1.2 正则表达式匹配更多模式

  1. 利用括号分组
    添加括号将在正则表达式中创建“分组”(\d\d\d)-(\d\d\d-\d\d\d\d)。然后可以使用group()匹配对象方法,从一个分组中获取匹配的文本。
  2. 用管道匹配多个分组
    字符|称为“管道”。希望匹配许多表达式中的一个时,就可以使用它。例如,正则表达式r’Batman|Tina Fey’将匹配’Batman’或’Tina Fey’。
  3. 用问号实现可选匹配
    有时候,想匹配的模式是可选的。就是说,不论这段文本在不在,正则表达式都会认为匹配。字符?表明它前面的分组在这个模式中是可选的。也可以理解为匹配这个问号之前的分组零次或一次。
  4. 用星号匹配零次或多次
    *(称为星号)意味着“匹配零次或多次”,即星号之前的分组,可以在文本中出现任意次。它可以完全不存在,或一次又一次地重复。
  5. 用加号匹配一次或多次
    加号+前面的分组必须“至少出现一次
  6. 用花括号匹配特定次数
    • 如果想要一个分组重复特定次数,就在正则表达式中该分组的后面,跟上花括号包围的数字。例如,正则表达式(Ha){3}将匹配字符串’HaHaHa’。
    • 除了一个数字,还可以指定一个范围,即在花括号中写下一个最小值、一个逗号和一个最大值。例如,正则表达式(Ha){1,2}将匹配 ‘Ha’ 和 ‘HaHa’。
    • 也可以不写花括号中的第一个或第二个数字,不限定最小值或最大值。例如,(Ha){3,}将匹配3 次或更多次实例。
  7. 用花括号和问号匹配非贪心模式
    Python 的正则表达式默认是“贪心”的,这表示在有二义的情况下,它们会尽可能匹配最长的字符串。花括号的“非贪心”版本匹配尽可能最短的字符串,即在
    结束的花括号后跟着一个问号。

1.3 findall()方法
search()将返回一个Match对象,包含被查找字符串中的“第一次”匹配的文本,而findall()方法将返回一组字符串,包含被查找字符串中的所有匹配。

  1. import re
  2. phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
  3. # search返回第一次匹配
  4. mo = phoneNumRegex.search('Cell: 415-555-9999 Work: 212-555-0000')
  5. mo.group()
  1. '415-555-9999'
  1. # findall返回所有结果
  2. phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
  3. phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000')
  1. ['415-555-9999', '212-555-0000']

1.4 字符分类

缩写字符分类 表示
\d 0 到9 的任何数字
\D 除0 到9 的数字以外的任何字符
\w 任何字母、数字或下划线字符(可以认为是匹配“单词”字符)
\W 除字母、数字和下划线以外的任何字符
\s 空格、制表符或换行符(可以认为是匹配“空白”字符)
\S 除空格、制表符和换行符以外的任何字符

1.5 建立自己的字符分类

  • 有时候你想匹配一组字符,但缩写的字符分类(\d、\w、\s 等)太宽泛。你可
    以用方括号定义自己的字符分类。例如,字符分类[aeiouAEIOU]将匹配所有元音字
    符,不论大小写。
  1. import re
  2. vowelRegex = re.compile(r'[aeiouAEIOU]')
  3. vowelRegex.findall('RoboCop eats baby food. BABY FOOD.')
  1. ['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O']
  • 可以使用短横表示字母或数字的范围。例如,字符分类[a-zA-Z0-9]将匹配所有小写字母、大写字母和数字。
  1. import re
  2. vowelRegex = re.compile(r'[a-zA-Z0-9]')
  3. vowelRegex.findall('RoboCop eats baby food. BABY FOOD.')
  1. ['R',
  2. 'o',
  3. 'b',
  4. 'o',
  5. 'C',
  6. 'o',
  7. 'p',
  8. 'e',
  9. 'a',
  10. 't',
  11. 's',
  12. 'b',
  13. 'a',
  14. 'b',
  15. 'y',
  16. 'f',
  17. 'o',
  18. 'o',
  19. 'd',
  20. 'B',
  21. 'A',
  22. 'B',
  23. 'Y',
  24. 'F',
  25. 'O',
  26. 'O',
  27. 'D']
  • 通过在字符分类的左方括号后加上一个插入字符(^),就可以得到“非字符类”。非字符类将匹配不在这个字符类中的所有字符。
  1. import re
  2. consonantRegex = re.compile(r'[^aeiouAEIOU]')
  3. consonantRegex.findall('RoboCop eats baby food. BABY FOOD.')
  1. ['R',
  2. 'b',
  3. 'C',
  4. 'p',
  5. ' ',
  6. 't',
  7. 's',
  8. ' ',
  9. 'b',
  10. 'b',
  11. 'y',
  12. ' ',
  13. 'f',
  14. 'd',
  15. '.',
  16. ' ',
  17. 'B',
  18. 'B',
  19. 'Y',
  20. ' ',
  21. 'F',
  22. 'D',
  23. '.']
  • 插入字符和美元字符
    正则表达式的开始处使用插入符号(^),表明匹配必须发生在被查找文本开始处。
    正则表达式的末尾加上美元符号,表示该字符串必须以这个正则表达式的模式结束。可以同时使用^和$,表明整个字符串必须匹配该模式。

1.6 通配字符

  1. .(句点)字符称为“通配符”。它匹配除了换行之外的所有字符。
  2. 用点-星(.*)表示“任意文本”。
  3. 通过传入re.DOTALL 作为re.compile()的第二个参数,可以让句点字符匹配所有字符,包括换行字符。

1.7 正则表达式符号总结


1.8 sub() 替换字符串

Regex对象的sub()方法需要传入两个参数。第一个参数是一个字符串,用于取代发现的匹配。第二个参数是一个字符串,即正则表达式。sub()方法返回替换完成后的字符串。

  1. import re
  2. namesRegex = re.compile(r'Agent \w+')
  3. namesRegex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.')
  1. 'CENSORED gave the secret documents to CENSORED.'

1.9 compile的第二个参数

  1. re.IGNORECASE 忽视大小写
  2. re.VERBOSE 编写注释
  3. re.DOTALL 句点表示所有字符(没有这个则表示除换行符外的所有字符)

2. 项目练习

2.1 电话号码和E-mail 地址提取程序

功能:在剪贴板的文本中查找电话号码和E-mail 地址,按一下Ctrl-A 选择所有文本,按下Ctrl-C 将它复制到剪贴板,然后运行程序。找到电话号码和E-mail地址,替换掉剪贴板中的文本。
文本例子地址:http://www.nostarch.com/contactus

主要步骤:
第1步:为电话号码创建一个正则表达式
第2步:为E-mail 地址创建一个正则表达式
第3步:在剪贴板文本中找到所有匹配
第4步:所有匹配连接成一个字符串,复制到剪贴板

  1. #! python3
  2. # Finds phone numbers and email addresses on the clipboard.
  3. # text:
  4. '''
  5. Contact Us
  6. No Starch Press, Inc.
  7. 245 8th Street
  8. San Francisco, CA 94103 USA
  9. Phone: 800.420.7240 or +1 415.863.9900 (9 a.m. to 5 p.m., M-F, PST)
  10. Fax: +1 415.863.9950
  11. Reach Us by Email
  12. General inquiries: info@nostarch.com
  13. Media requests: media@nostarch.com
  14. Academic requests: academic@nostarch.com (Please see this page for academic review requests)
  15. Help with your order: info@nostarch.com
  16. Reach Us on Social Media
  17. Twitter
  18. Facebook
  19. Instagram
  20. Pinterest
  21. 100.420.7240 x 123
  22. '''
  23. import pyperclip
  24. import re
  25. # 为电话号码创建一个正则表达式
  26. # 电话号码 phone
  27. phoneRegex = re.compile(r'''(
  28. (\d{3}|\(\d{3}\))? # area code
  29. (\s|-|\.)? # separator
  30. (\d{3}) # first 3 digits
  31. (\s|-|\.) # separator
  32. (\d{4}) # last 4 digits
  33. (\s*(ext|x|ext.)\s*(\d{2,5}))? # extension
  34. )''', re.VERBOSE)
  35. # 为E-mail 地址创建一个正则表达式
  36. # Create email regex. 邮件
  37. emailRegex = re.compile(r'''(
  38. [a-zA-Z0-9._%+-]+ # username
  39. @ # @ symbol
  40. [a-zA-Z0-9.-]+ # domain name
  41. (\.[a-zA-Z]{2,4}) # dot-something
  42. )''', re.VERBOSE)
  43. # TODO: Create email regex.
  44. # TODO: Find matches in clipboard text.
  45. # TODO: Copy results to the clipboard.
  46. # Find matches in clipboard text.
  47. # 获得剪切板文件
  48. text = str(pyperclip.paste())
  49. matches = []
  50. a = phoneRegex.findall(text)
  51. for groups in phoneRegex.findall(text):
  52. # 读取数字
  53. phoneNum = '-'.join([groups[1], groups[3], groups[5]])
  54. # 如果没有分号
  55. if groups[8] != '':
  56. phoneNum += ' x' + groups[8]
  57. matches.append(phoneNum)
  58. for groups in emailRegex.findall(text):
  59. matches.append(groups[0])
  60. # Copy results to the clipboard.
  61. if len(matches) > 0:
  62. pyperclip.copy('\n'.join(matches))
  63. print('Copied to clipboard:')
  64. print('\n'.join(matches))
  65. else:
  66. print('No phone numbers or email addresses found.')
  1. Copied to clipboard:
  2. 800-420-7240
  3. 415-863-9900
  4. 415-863-9950
  5. 100-420-7240 x123
  6. info@nostarch.com
  7. media@nostarch.com
  8. academic@nostarch.com
  9. info@nostarch.com

2.2 强口令检测

写一个函数,它使用正则表达式,确保传入的口令字符串是强口令。强口令的定义是:长度不少于8 个字符,同时包含大写和小写字符,至少有一位数字。

  1. import re
  2. import pyperclip
  3. def detect(text):
  4. if len(text)<8:
  5. return False
  6. test1=re.compile(r'([0-9])')
  7. result1=test1.search(text)
  8. if result1==None:
  9. return False
  10. test2=re.compile(r'([A-Z])')
  11. result2=test2.search(text)
  12. if result2==None:
  13. return False
  14. test3=re.compile(r'([a-z])')
  15. result3=test3.search(text)
  16. if result3==None:
  17. return False
  18. return True
  19. text='uusssZmi0546'
  20. status=detect(text)
  21. print(status)
  1. True

2.3 strip()的正则表达式版本

写一个函数,它接受一个字符串,做的事情和strip()字符串方法一样。如果只传入了要去除的字符串,没有其他参数,那么就从该字符串首尾去除空白字符。否
则,函数第二个参数指定的字符将从该字符串中去除。

  1. import re
  2. def my_strip(text,param=''):
  3. if len(param)<1:
  4. param='\s'
  5. params_begin= r'^[{}]*'.format(param)
  6. params_end= r'[{}]*$'.format(param)
  7. my_begin=re.compile(params_begin,re.I)
  8. my_end=re.compile(params_end,re.I)
  9. my=my_begin.sub('', text)
  10. text=my_end.sub('', my)
  11. return text
  12. text='SpamSpamBaconSpamEggsSpamSpam'
  13. param='SPAM'
  14. text=my_strip(text,'SPAM')
  15. print(text)
  1. BaconSpamEgg

[python]《Python编程快速上手:让繁琐工作自动化》学习笔记1的更多相关文章

  1. python学习笔记整理——字典

    python学习笔记整理 数据结构--字典 无序的 {键:值} 对集合 用于查询的方法 len(d) Return the number of items in the dictionary d. 返 ...

  2. VS2013中Python学习笔记[Django Web的第一个网页]

    前言 前面我简单介绍了Python的Hello World.看到有人问我搞搞Python的Web,一时兴起,就来试试看. 第一篇 VS2013中Python学习笔记[环境搭建] 简单介绍Python环 ...

  3. python学习笔记之module && package

    个人总结: import module,module就是文件名,导入那个python文件 import package,package就是一个文件夹,导入的文件夹下有一个__init__.py的文件, ...

  4. python学习笔记(六)文件夹遍历,异常处理

    python学习笔记(六) 文件夹遍历 1.递归遍历 import os allfile = [] def dirList(path): filelist = os.listdir(path) for ...

  5. python学习笔记--Django入门四 管理站点--二

    接上一节  python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...

  6. python学习笔记--Django入门0 安装dangjo

    经过这几天的折腾,经历了Django的各种报错,翻译的内容虽然不错,但是与实际的版本有差别,会出现各种奇葩的错误.现在终于找到了解决方法:查看英文原版内容:http://djangobook.com/ ...

  7. python学习笔记(一)元组,序列,字典

    python学习笔记(一)元组,序列,字典

  8. Pythoner | 你像从前一样的Python学习笔记

    Pythoner | 你像从前一样的Python学习笔记 Pythoner

  9. OpenCV之Python学习笔记

    OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书< ...

  10. python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹

    python学习笔记(五岁以下儿童) 深拷贝-浅拷贝 浅拷贝就是对引用的拷贝(仅仅拷贝父对象) 深拷贝就是对对象的资源拷贝 普通的复制,仅仅是添加了一个指向同一个地址空间的"标签" ...

随机推荐

  1. C# 传不定参数

    1 public class MyClass 2 { 3 public static void UseParams(params int[] list) 4 { 5 for (int i = 0; i ...

  2. JavaScript基本语法(函数与对象)

    3.函数 #①内置函数 内置函数:系统已经声明好了可以直接使用的函数. #[1]弹出警告框 alert("警告框内容");   #[2]弹出确认框 用户点击『确定』返回true,点 ...

  3. 使用 etcdadm 快速、弹性部署 etcd 集群

    Etcd 是一个可靠的分布式键值存储, 常用于分布式系统关键数据的存储:而 etcdadm 是一个用于操作 etcd 集群的命令行工具,它可以轻松创建集群.向现有集群添加成员.从现有集群中删除成员等操 ...

  4. 5.pygame快速入门-精灵和精灵组

    在之前案例中,图像加载.位置变化.绘制图像都需要编写代码分别处理 pygame提供了两个类简化开发步骤 pygame.sprite.Sprite #精灵,存储图像数据image和位置rect的对象 p ...

  5. webgl(three.js)3D光伏,3D太阳能能源,3D智慧光伏、光伏发电、清洁能源三维可视化解决方案——第十六课

    序: 能源是文明和发展的重要保障,人类命运不可避开的话题,无论是战争还是发展,都有它存在的身影.从石器时代到现代文明,人类的能源应用在进步,也在面临能源枯竭的危机与恐惧,而开发与应用可再生能源才是解决 ...

  6. python的一些运算符

    # 1.算术运算符 print('1.算术运算符') # 1.1 + 求和 a = 10 b = 20 c = a + b print(c) print('a+b={}'.format(c)) pri ...

  7. 上下文管理器 context managet

    定义:实现了上下文管理协议的对象,主要用于保存和恢复各种全局状态,关闭文件等,它本身就是一种装饰器. with语句 with语句就是为支持上下文管理器而存在的

  8. Vue3组件间传值

    12种方式 1. 父组件 ./father.vue 点击查看代码 <template> <h1>father:</h1> <h3>子组件传过来的:{{ ...

  9. Seata 1.5.2 源码学习(事务执行)

    关于全局事务的执行,虽然之前的文章中也有所涉及,但不够细致,今天再深入的看一下事务的整个执行过程是怎样的. 1. TransactionManager io.seata.core.model.Tran ...

  10. python贪心算法——以“修理牛棚”题目为例

    [USACO1.3]修理牛棚 Barn Repair 题目描述 在一个月黑风高的暴风雨夜,Farmer John 的牛棚的屋顶.门被吹飞了 好在许多牛正在度假,所以牛棚没有住满. 牛棚一个紧挨着另一个 ...