正则表达式

re.match函数

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

1
re.match(pattern, string, flags=0)
  • pattern:匹配的正则表达式
  • string:要匹配的字符串。
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

匹配成功re.match方法返回一个匹配的对象,否则返回None。

使用group(num) 或 groups() 匹配对象函数来获取匹配表达式

  • group(num=0):匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
  • groups():返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import re
print(re.match('www', 'www.baidu.com').span()) # 在起始位置匹配
print(re.match('com', 'www.baidu.com')) # 不在起始位置匹配

line = "Cats are smarter than dogs"

matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)

if matchObj:
print "matchObj.group() : ", matchObj.group()
print "matchObj.group(1) : ", matchObj.group(1)
print "matchObj.group(2) : ", matchObj.group(2)
else:
print "No match!!"
1
2
3
4
5
6
# 输出
(0, 3)
None
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter

r'(.*) are (.*?) .*' 解析

  • r 表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。但是这个字符串里没有反斜杠,所以这个 r 可有可无。
  • (.*) 第一个匹配分组,.* 代表匹配除换行符之外的所有字符
  • (.*?) 第二个匹配分组,.*? 后面多个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符
  • 后面的一个 .* 没有括号包围,所以不是分组,匹配效果和第一个一样,但是不计入匹配结果中。
  • matchObj.group() 等同于 matchObj.group(0),表示匹配到的完整文本字符
  • matchObj.group(1) 得到第一组匹配结果,也就是(.*)匹配到的
  • matchObj.group(2) 得到第二组匹配结果,也就是(.*?)匹配到的

因为只有匹配结果中只有两组,所以如果填 3 时会报错。

re.search方法

re.search 扫描整个字符串并返回第一个成功的匹配。

1
re.search(pattern, string, flags=0)

匹配成功re.search方法返回一个匹配的对象,否则返回None

1
2
3
import re
print(re.search('www', 'www.baidu.com').span()) # 在起始位置匹配
print(re.search('com', 'www.baidu.com').span()) # 不在起始位置匹配
1
2
3
# 输出:
(0, 3)
(11, 14)

re.match与re.search的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re

line = "Cats are smarter than dogs";

matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
print "match --> matchObj.group() : ", matchObj.group()
else:
print "No match!!"

matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
print "search --> matchObj.group() : ", matchObj.group()
else:
print "No match!!"
1
2
3
# 输出:
No match!!
search --> matchObj.group() : dogs

检索和替换

re.sub用于替换字符串中的匹配项

1
re.sub(pattern, repl, string, count=0, flags=0)
  • pattern : 正则中的模式字符串。
  • repl : 替换的字符串,也可为一个函数。
  • string : 要被查找替换的原始字符串。
  • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
1
2
3
4
5
6
7
8
9
10
11
import re

phone = "2004-959-559 # 这是一个国外电话号码"

# 删除字符串中的 Python注释
num = re.sub(r'#.*$', "", phone)
print "电话号码是: ", num

# 删除非数字(-)的字符串
num = re.sub(r'\D', "", phone)
print "电话号码是 : ", num
1
2
3
# 输出:
电话号码是: 2004-959-559
电话号码是 : 2004959559

re.compile 函数

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。

1
re.compile(pattern[, flags])

findall

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。match 和 search 是匹配一次 findall 匹配所有

1
findall(string[, pos[, endpos]])
  • string : 待匹配的字符串。
  • pos : 可选参数,指定字符串的起始位置,默认为 0。
  • endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
1
2
3
4
5
6
7
8
import re

pattern = re.compile(r'\d+') # 查找数字,用于匹配至少一个数字
result1 = pattern.findall('baidu 123 google 456')
result2 = pattern.findall('bai88bai123google456', 0, 10)

print(result1)
print(result2)
1
2
3
# 输出
['123', '456']
['88', '12']

re.finditer

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

1
re.finditer(pattern, string, flags=0)

re.split

split 方法按照能够匹配的子串将字符串分割后返回列表

1
re.split(pattern, string[, maxsplit=0, flags=0])
1
2
3
4
5
6
7
8
9
10
>>>import re
>>> re.split('\W+', 'baidu, baidu, baidu.')
['baidu', 'baidu', 'baidu', '']
>>> re.split('(\W+)', ' baidu, baidu, baidu.')
['', ' ', 'baidu', ', ', 'baidu', ', ', 'baidu', '.', '']
>>> re.split('\W+', ' baidu, baidu, baidu.', 1)
['', 'baidu, baidu, baidu.']

>>> re.split('a*', 'hello world') # 对于一个找不到匹配的字符串而言,split 不会对其作出分割
['hello world']

正则表达式对象

re.RegexObject

re.compile() 返回 RegexObject 对象。

re.MatchObject

group() 返回被 RE 匹配的字符串。

  • start() 返回匹配开始的位置
  • end() 返回匹配结束的位置
  • span() 返回一个元组包含匹配 (开始,结束) 的位置

正则表达式常用符号解释

  • \ : 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,’n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\\‘ 匹配 “\“ 而 “\(“ 则匹配 “(“
  • ^ : 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline(多行匹配) 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置
  • $ : 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置
  • * : 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}
    • : 匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}
  • ? : 匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}
  • {n} : n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o
  • {n,} : n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’
  • {n,m} : m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格,贪婪模式
  • ? : 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,’o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’
  • . : 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式
  • […] : 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,’m’或’k’
  • [^…] : 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
  • a| b : 匹配a或b
  • (?imx) : 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域
  • \w : 匹配字母数字及下划线
  • \W : 匹配非字母数字及下划线
  • \s : 匹配任意空白字符,等价于 [\t\n\r\f].
  • \S : 匹配任意非空字符,等价于 [^ \f\n\r\t\v]
  • \d : 匹配任意数字,等价于 [0-9].
  • \D : 匹配任意非数字,等价于 [^0-9].
  • \A : 匹配字符串开始
  • \Z : 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
  • \z : 匹配字符串结束
  • \G : 匹配最后匹配完成的位置。
  • \b : 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
  • \B : 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
  • \n, \t, 等. : 匹配一个换行符。匹配一个制表符。等
  • \1…\9 : 匹配第n个分组的内容。
  • \10 : 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

正则表达式修饰符 - 可选标志

修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解