- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
7.2 用正则表达式查找文本模式
前面的电话号码查找程序能工作,但它使用了很多代码,做的事却有限:isPhoneNumber()函数有17行,但只能查找一种电话号码模式。像415.555.4242或(415) 555-4242这样的电话号码格式,该怎么办呢?如果电话号码有分机,例如415-555-4242 x99,该怎么办呢?isPhoneNumber()函数在验证它们时会失败。你可以添加更多的代码来处理额外的模式,但还有更简单的方法。
正则表达式,简称为regex,是文本模式的描述方法。例如,\d 是一个正则表达式,表示一位数字字符,即任何一位 0 到 9 的数字。Python 使用正则表达式\d\d\d-\d\d\d-\d\d\d\d,来匹配前面isPhoneNumber()函数匹配的同样文本:3 个数字、一个短横线、3 个数字、一个短横线、4 个数字。所有其他字符串都不能匹配\d\d\d-\d\d\d-\d\d\d\d正则表达式。
但正则表达式可以复杂得多。例如,在一个模式后加上花括号包围的3({3}),就是说,“匹配这个模式3次”。所以较短的正则表达式\d{3}-\d{3}-\d{4},也匹配正确的电话号码格式。
7.2.1 创建正则表达式对象
Python中所有正则表达式的函数都在re模块中。在交互式环境中输入以下代码,导入该模块:
>>> import re
注意
本章后面的大多数例子都需要re模块,所以要记得在你写的每个脚本开始处导入它,或重新启动IDLE时。否则,就会遇到错误消息NameError: name 're' is not defined。
向re.compile()传入一个字符串值,表示正则表达式,它将返回一个Regex模式对象(或者就简称为Regex对象)。
要创建一个Regex对象来匹配电话号码模式,就在交互式环境中输入以下代码(回忆一下,\d表示“一个数字字符”,\d\d\d-\d\d\d-\d\d\d\d是正确电话号码模式的正则表达式)。
>>> phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
现在phoneNumRegex变量包含了一个Regex对象。
7.2.2 匹配Regex对象
Regex对象的search()方法查找传入的字符串,寻找该正则表达式的所有匹配。如果字符串中没有找到该正则表达式模式,search()方法将返回None。如果找到了该模式,search()方法将返回一个Match对象。Match对象有一个group()方法,它返回被查找字符串中实际匹配的文本(稍后我会解释分组)。例如,在交互式环境中输入以下代码:
>>> phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') >>> mo = phoneNumRegex.search('My number is 415-555-4242.') >>> print('Phone number found: ' + mo.group()) Phone number found: 415-555-4242
变量名mo是一个通用的名称,用于Match对象。这个例子可能初看起来有点复杂,但它比前面的isPhoneNumber.py程序要短很多,并且做的事情一样。
这里,我们将期待的模式传递给re.compile(),并将得到的Regex对象保存在phoneNumRegex中。然后我们在phoneNumRegex上调用search(),向它传入想查找的字符串。查找的结果保存在变量mo中。在这个例子里,我们知道模式会在这个字符串中找到,所以我们知道会返回一个Match对象。知道mo包含一个Match对象,而不是空值None,我们就可以在mo变量上调用group(),返回匹配的结果。将mo.group()写在打印语句中,显示出完整的匹配,即415-555-4242。
向re.compile()传递原始字符串
回忆一下,Python中转义字符使用倒斜杠(\)。字符串'\n'表示一个换行字符,而不是倒斜杠加上一个小写的n。你需要输入转义字符\,才能打印出一个倒斜杠。所以'\n'表示一个倒斜杠加上一个小写的n。但是,通过在字符串的第一个引号之前加上r,可以将该字符串标记为原始字符串,它不包括转义字符。
因为正则表达式常常使用倒斜杠,向re.compile()函数传入原始字符串就很方便,而不是输入额外得到斜杠。输入r'\d\d\d-\d\d\d-\d\d\d\d',比输入'\d\d\d-\d\d\d-\d\d\d\d'要容易得多。
7.2.3 正则表达式匹配复习
虽然在Python中使用正则表达式有几个步骤,但每一步都相当简单。
1.用import re导入正则表达式模块。
2.用re.compile()函数创建一个Regex对象(记得使用原始字符串)。
3.向Regex对象的search()方法传入想查找的字符串。它返回一个Match对象。
4.调用Match对象的group()方法,返回实际匹配文本的字符串。
注意
虽然我鼓励你在交互式环境中输入示例代码,但你也应该利用基于网页的正则表达式测试程序。它可以向你清楚地展示,一个正则表达式如何匹配输入的一段文本。我推荐的测试程序位于http://regexpal.com/。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论