15.1 引言/动机

处理文本和数据是件大事。如果你不相信我说的话,请仔细看看现如今的计算机主要都在做些什么工作:文字处理、网页填表、来自数据库的信息流、股票报价信息、新闻列表,这个清单还会不断地增长。因为我们可能不知道这些需要计算机编程处理文本或数据的具体内容,所以能把这些文本或数据以某种可被计算机识别和处理的模式表达出来是非常有用的。

假设我在运营一个电子邮件档案公司,而你是我的一位顾客,比如说,你想获得自己去年二月份收发的所有邮件,如果我能设计一个计算机程序来整理信息然后将它转发给你,而不是通过人工方法通读你的邮件后再手动地处理你的请求,那会非常不错。因为如果有人看了你的邮件信息,哪怕只是用眼睛瞄一下邮件上的时间,你可能都会对此感到担心(甚至愤怒)。又比如,你可能会认为凡是带有 “ILOVEYOU”这样主题的邮件都是已感染病毒的信息,并要求从你的个人邮箱中删除它们。这就引出一个问题,我们如何通过编程使计算机具有在文本中检索某种模式的能力。

正则表达式(RE)为高级文本模式匹配,以及搜索-替代等功能提供了基础。正则表达式(RE)是一些由字符和特殊符号组成的字符串,它们描述了这些字符和字符的某种重复方式,因此能按某种模式匹配一个有相似特征的字符串的集合,因此能按某模式匹配一系列有相似特征的字符串,见图15-1。换句话说,它们能匹配多个字符串——一个只能匹配一个字符串的RE模式是乏味且毫无作用的,你说是不是?

15.1 引言/动机 - 图1

图  15-1

正则表达式引擎

图 15-1 你可以用这个正则表达式匹配有效的Python标识符。 “[A-Za-z]\w+”的含义是:第一个字符是字母,即,由大写字母A~Z或是小写字母a~z组成,它后面至少跟有一个(或更多)由字母或数字组成的字符(\w)。如图,你看到有很多字符串被过滤,只有那些符合我们要求的RE模式的字符串被筛选出来。比如,“4xZ”,因为它是以数字开头的,所以被过滤了。

Python通过标准库的re模块支持正则表达式(RE),本节我们将简要地介绍一下。限于篇幅,内容将仅涉及Python编程中正则表达式(RE)方面最常见的内容。你们(对正则)的经验(熟悉程度)肯定不同。我们强烈建议你阅读一些官方帮助文档和与此主题有关的文本。那么你对字符串的理解方式就会有所改变。

15.1 引言/动机 - 图2核心笔记:搜索与匹配的比较

本章通篇涉及到对搜索和匹配用法的讲述。当我们完全讨论与字符串中模式有关的正则表达式时,我们会用术语“匹配”(matching),指的是术语“模式匹配”(pattern-matching)。在Python专门术语中,有两种主要方法完成模式匹配:搜索(searching)和匹配(matching)。搜索,即在字符串任意部分中搜索匹配的模式,而匹配是指,判断一个字符串能否从起始处全部或部分的匹配某个模式。搜索通过search()函数或方法来实现,而匹配是以调用match()函数或方法实现的。总之,当我们说模式的时候,我们全部使用术语“匹配” (matching);我们按照Python如何完成模式匹配的方式来区分“搜索”和“匹配” 。

你的第一个正则表达式

我们上面已经提到,正则表达式是含有文本和特别字符的字符串,这些文本和特别字符描述的模式可以识别各种字符串。我们还简单阐述了正则表达式字母表,以及用于匹配通用文本的正则表达式字母表——所有大小写字母及数字的集合。也存在特别的字母表,比如,只含有字符“0”和“1”的字母表。该字母表可以表示所有二进制整型的集合,即,“0,” “1,” “00,” “01,” “10,” “11,” “100,”等。

让我们看看正则表达式的基本情况,虽然正则表达式常被视为是“高级主题”,但是有时候它们也是非常简单的。我们列出一些用一般文本的标准字母组成简单的正则表达式及它们所描述的字符串。以下的正则表达式是最基本、最普通的。它们仅由一个字符串定义了一个模式,该模式仅匹配这个字符串本身,该字符串由正则表达式定义。以下是正则表达式(RE)和匹配它们的字符串。

正则表达式模式匹配的字符串。

15.1 引言/动机 - 图3

上表中第一个正则表达式模式是“foo”。这个模式不包含任何特殊符号去匹配其他符号,它仅匹配自身所描述的,所以只有字符串“foo”匹配此模式。同理,“Python”和“abcl23”也一样。正则表达式的强大之处在于特殊符号的应用,特殊符号定义了字符集合、子组匹配、模式重复次数。正是这些特殊符号使得一个正则表达式可以匹配字符串集合而不只是一个字符串。