Python 正则表达式例子 - Re Match Search FindAll

Tags: python regex

正则表达式,又称正规表示法、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个 句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

正则表达式并不是 Python 独有的功能,基本上所有的编程语言都支持正则表达式。这篇文章中,我们将介绍如何在 Python 语言中正则表达式的特点以及使用方法。

在 Python 中与正则表达式相关的包是 re,使用下面代码导入:

 >>> import re

原始字符串(Raw Strings)

在 Python 中 "\" 用来转义字符,在解析过程中如果解析器遇到反斜线和特定字符的组合,那么反斜线以及特定字符组合的字符串会被替换为特殊字符串(比如:'\n' 会被替换为换行符)

当使在 Python 中使用正则表达式时,这个行为会带来一些问题,因为在 re 包中,同样使用正则表达式来转义特殊正则表达式字符(比如: * 或 +)。

上面的情况意味着,你有时候需要转义转义字符自身(绕口吧,我自己把自己翻晕了。这种情况通常是特定的字符串即需要由 Python 字符串解析,也需要被正则表达式引擎解析)。当然,其他情况下你不需要考虑这个问题(字符串仅由正则表达式解析)

因此,为了避免想通你的大脑来确定到底需要多少个反斜线('\\' = \),我们可以使用原始字符串(Raw Strings)。

使用原始字符串很简单,仅需要在字符串的左边引号前增加一个字母 'r'。对于原始字符串,Python 解析器不会对字符串任何字串进行替换,它会完整保持字符串原始定义,比如:

>>> string = 'This is a\nnormal string'
>>> rawString = r'and this is a\nraw string'
>>> print string
This is a
normal string

>>> print rawString
and this is a\nraw string

在 Python 中使用正则表达式

Python 的 re 包有一些方法用来执行字符串查询:

  • re.match()

  • re.search()

  • re.findall()

每个方法都接受一个模式定义以及用来查询和匹配的字符串。后面的内容中我们回逐个介绍这些方法的使用方法和区别。

使用 re.match - 匹配开头

先来看看 match() 方法,这个方法会从符串的开头匹配模式(也就是说字符串从第一个字符开始就需要能够匹配到模式,字符串中间的某些字符能够匹配模式是不行的),如果匹配到会返回 Match 对象,否则返回 None。

比如,我们使用模式 'dog' 来匹配 'dog cat dog' 是可以匹配的:

>>> re.match(r'dog', 'dog cat dog')
<_sre.SRE_Match object at 0xb743e720>
>>> match = re.match(r'dog', 'dog cat dog')
>>> match.group(0)
'dog'

我们后面会更详细介绍 group() 方法,在这里,你仅需要知道调用 group(0) 就可以返回匹配的内容。

不过,如果我们将模式换成 'cat',那么就不会匹配上面的字符串了:

>>> re.match(r'cat', 'dog cat dog')
>>>

使用 re.search - 匹配任意位置

search() 方法和 match() 方法很类似,区别在于 search() 方法不仅仅只从开头匹配字符串,它会在任意位置匹配字符串,因此修改上面例子使用 search() 方法可以匹配 'cat' 模式。

search(r'cat', 'dog cat dog')
>>> match.group(0)
'cat'

search() 方法会在匹配到第一个匹配项时退出,因此上面例子中如果使用 'dog' 进行匹配,则只会匹配到第一个 'dog':

  >>> match = re.search(r'dog', 'dog cat dog')
  >>> match.group(0)
  'dog'

使用 re.findall - 匹配所有内容

在 Python 中我使用最多的查询方法基本上就是 findall() 了。当调用 findall() 进行匹配时会返回字符串中所有匹配的匹配对象(我们晚些会介绍匹配对象 Match Object),参考下面示例:

  >>> re.findall(r'dog', 'dog cat dog')
  ['dog', 'dog']
  >>> re.findall(r'cat', 'dog cat dog')
  ['cat']

使用 match.startmatch.end 方法

那么我们前面提到的匹配对象(Match Object)到底是什么?相对于直接返回匹配的字符串来说,search()match() 方法会返回 matches 对象,这个对象是匹配的子字符串的包装。

在前面的例子中我们看到了使用 matches 对象的 group() 方法的示例(当使用分组时,match 对象是非常有用的)。当然,match 对象还包含匹配字符串更多的信息。

比如,match 对象可以告诉我们匹配字符串在源字符串中的位置(起始和终止位置),比如:

  >>> match = re.search(r'dog', 'dog cat dog')
  >>> match.start()
  0
  >>> match.end()
  3

这些信息是非常有用的。

使用 match.group 按照序号分组

正如前面提到的, match 对象的分组功能非常有用。分组可以用来在所有的匹配中找到特定的匹配。我们可以认为分组是用来单独标识源字符串的所有匹配中某个匹配的方式。下面的几个例子将介绍如何使用分组。

 >>> contactInfo = 'Doe, John: 555-1212'

上面的字符串是某个人的地址,我们可以使用下面的正则表达式来匹配这个字符串:

 >>> re.search(r'\w+, \w+: \S+', contactInfo)
  <_sre.SRE_Match object at 0xb74e1ad8>

使用括号括住正则表达式的某些部分('('和')'),这样我们可以将部分内容进行分组并且使用这些分组。

>>> match = re.search(r'(\w+), (\w+): (\S+)', contactInfo)

这些分组可以使用 group() 方法取得,分组根据源字符串从左到右匹配的顺序以数字进行编号(从1开始):

  >>> match.group(1)
  'Doe'
  >>> match.group(2)
  'John'
  >>> match.group(3)
  '555-1212'

分组序号从 1 开始的原因是,序号 0 用来保存整个匹配项(在前面的 match()search() 部分我们使用过)

  >>> match.group(0)
  'Doe, John: 555-1212'

按照名称分组

有些时候,特别是正则表达式包含很多分组的时候,使用数字对分组进行编号非常麻烦而且不好记忆。Python 支持为分组设置名称,参考下面语句:

>>> match = re.search(r'(?P<last>\w+), (?P<first>\w+): (?P<phone>\S+)', contactInfo)

我们还是使用 group 方法来取得分组,不过这次我们使用分组的名称而不是序号,参考下面代码:

  >>> match.group('last')
  'Doe'
  >>> match.group('first')
  'John'
  >>> match.group('phone')
  '555-1212'

上面的代码好理解多了。我们可以设想,当正则表达式越来越复杂,理解表达式中的分组会越来越困难,因此最好为分组命名,这样可以在代码中明确你的编码思路和意图。

使用 fetchall() 方法时同样可以使用分组,尽管这个方法并不返回 match 对象。相反,fetchall() 方法会返回一个元组列表,元组中的每个元素对应正则表达式中相应的分组,参考下例:

  >>> re.findall(r'(\w+), (\w+): (\S+)', contactInfo)
  [('Doe', 'John', '555-1212')]

不过,在使用 findall() 方法时,是不能使用分组命名的。

总结

在这篇文章中,我们介绍了 Python 正则表达式的基础内容,我们学习了原始字符串(Raw Strings)、正则表达式的基础函数 match(), search()findall()以及如何使用分组。

任何时候,Python 官方文档中的 re 包 都是你需要经常参考的文档。

后面的文章中,我们会深入讨论 Python 的正则表达式,我们会讨论如何在更大的范围内进行匹配,如何替换字符串以及如何用正则表达式将文本文件解析到 Python 的数据结构中。

参考:

深入 Python 正则表达式

如何使用 Python 正则表达式解析文本文件

本文链接:http://www.4byte.cn/learning/88475/python-zheng-ze-biao-da-shi-li-zi-re-match-search-findall.html



相关文章