Python 正则表达式


正则表达式是一种描述匹配模式的字符串。用来在一个字符串中查找、替换指定模式的子字符串。


元字符(Metacharacter)

元字符是有特殊含义的字符。元字符包含:?*+.^$()[]{}|\。除了元字符外的其它字符都匹配自己。

\字符是转义字符,会改变紧跟在它后面的字符的意义。如果要匹配元字符,需要在元字符前加上\

字符组(Character Class)

字符组是包含在中括号中的字符集合。字符组只匹配字符串中的一个字符。

字符组有下面2种:

  • 简单字符组,例如[abc],匹配a或b或c。
  • 否定(Negation)字符组,例如[^abc],除去a、b、c以外的所有其它字符。

预定义的字符组,常用字符组的简写形式。

预定义字符组有下面几种:

  • .,匹配任何字符(可能不包含换行符)。
  • \d,数字,即[0-9]。
  • \D,非数字,即[^0-9]。
  • \s,空白字符,即[ \t\n\v\f\r]。
  • \S,非空白字符,即[^\s]。
  • \w,单词字符,即[a-zA-Z_0-9]。
  • \W,非单词字符,即[^\w]。

量词(Quantifier)

量词用于指定匹配出现的次数。

有下面几种量词:

  • x?,匹配0个或1个x。
  • x*,匹配0或多个x。
  • x+,匹配1或多个x。
  • x{n},匹配n个x。
  • x{n,},匹配至少n个x。
  • x{n,m},匹配至少n个x,但不超过m个x。

使用量词时默认是贪婪(greedy)匹配,如果在量词后面再加上?则表示使用惰性(reluctant)匹配。

捕获组(Capturing Group)

捕获组将多个字符当做一个单元看待。在多个字符前后加上括号(...)创建一个捕获组。

匹配的捕获组可以在后面使用,称为反向引用(backreference)。捕获组从左到右被编号。捕获组0表示整个字符串。反向引用使用\后跟捕获组编号来引用捕获组的值,例如\1

也可以对分组进行命名和通过名字引用分组:

对分组命名:(?P<name>...)

引用命名的分组:(?P=name)

匹配边界(Boundary Matcher)

匹配边界指匹配开始和结束的位置。

有下面几种匹配边界:

  • ^,行的开始。
  • $,行的结束。
  • \b,单词边界。
  • \B,非单词边界。
  • \A,输入的开始位置。
  • \Z,输入的结束位置。

匹配和查找

匹配(match)和查找(search)都用于从一个字符串中提取子字符串,或用于判断一个字符串是否匹配指定模式。不同的是匹配是从字符串的开始位置匹配模式,而查找可以从字符串的任意位置匹配模式。

下面是匹配和查找的例子:

#!/usr/bin/python
import re

p = re.compile(r'\dabc', re.I)
search = p.search('A2abcd')
match = p.match('A2abcd')

if search:
    print('search : ', search.group())  # 2abc
if match:
    print('match : ', match.group())

if re.search(r'\dabc', 'A2abcd'):
    print('search ok')  # search ok

search2 = re.search(r'(\da)(.*)\d', 'A2abc3d')
if search2:
    print('group1 :', search2.group(1))     # 2a
    print('group2 :', search2.group(2))     # bc

替换

替换(sub)用来将字符串中的所有匹配指定模式的地方替换成指定的字符串。

下面是替换的例子:

#!/usr/bin/python
import re

print(re.sub("p*", "", "apple"))    # ale
print(re.sub(r"a(.)\1le", r"\1", "apple"))  # p

拆分

拆分(split)用来根据指定模式拆分字符串。

下面是拆分的例子:

#!/usr/bin/python
import re

print(re.split("\d ", "1 apple 2 pear"))    # ['', 'apple ', 'pear']