匹配符:
^ 匹配字符串开始位置。在多行字符串模式匹配每一行的开头。
$ 匹配字符串结束位置。在多行字符串模式匹配每一行的结尾。
. 匹配除了换行符外的任何字符,在 alternate 模式(re.DOTALL)下它甚至可以匹配换行。
\A 匹配字符串开头
\Z 匹配字符串结尾
\b 匹配一个单词边界。即 \w 与 \W 之间。
\B 匹配一个非单词边界;相当于类 [^\b]。
\d 匹配一个数字。
\D 匹配一个任意的非数字字符。
\s 匹配任何空白字符;它相当于类 [
\r\f\v]。
\S 匹配任何非空白字符;它相当于类 [^
\r\f\v]。
\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。
x? 匹配可选的x字符。即是0个或者1个x字符。
x* 匹配0个或更多的x。
x+ 匹配1个或者更多x。
x{n,m} 匹配n到m个x,至少n个,不能超过m个。
(a|b|c) 匹配单独的任意一个a或者b或者c。
(x) 捕获组,小括号括起来即可,它会记忆它匹配到的字符串。
可以用 re.search() 返回的匹配对象的 groups()函数来获取到匹配的值。
\1 记忆组,它表示记住的第一个分组;如果有超过一个的记忆分组,可以使用 \2 和 \3等等。
记忆组的内容也要小括号括起来。
(?iLmsux) iLmsux的每个字符代表一种匹配模式
re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
re.M(re.MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
re.S(re.DOTALL): 点任意匹配模式,改变'.'的行为
re.L(re.LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
re.U(re.UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
re.X(re.VERBOSE): 松散正则表达式模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。
(?:表达式) 无捕获组。与捕获组表现一样,只是没有内容。
(?P表达式) 命名组。与记忆组一样,只是多了个名称。
(?P=name) 命名组的逆向引用。
(?#...) “#”后面的将会作为注释而忽略掉。例如:“ab(?#comment)cd”匹配“abcd”
(?=...) 之后的字符串需要匹配表达式才能成功匹配。不消耗字符串内容。例:“a(?=\d)”匹配“a12”中的“a”
(?!...) 之后的字符串需要不匹配表达式才能成功匹配。不消耗字符串内容。例:“a(?!\d)”匹配“abc”中的“a”
(?<=...) 之前的字符串需要匹配表达式才能成功匹配。不消耗字符串内容。例:“(?<=\d)a”匹配“2a”中的“a”
(?<!...) 之前的字符串需要不匹配表达式才能成功匹配。不消耗字符串内容。例:“(?<!\d)a”匹配“sa”中的“a”
注:上面4个表达式的里面匹配的内容只能是一个字符,多个则报错。
(?(id/name)yes-pattern|no-pattern) 如果编号为 id 或者别名为 name 的组匹配到字符串,
则需要匹配yes-pattern,否则需要匹配no-pattern。 “|no-pattern”可以省略。如:“(\d)ab(?(1)\d|c)”匹配到“1ab2”和“abc“
# 必须引入 re 标准库
import re
# 字符串替换: sub() 与 subn()
s='100 NORTH MAIN ROAD'
# 将字符串结尾的单词“ROAD”替换成“RD.”;该 re.sub() 函数执行基于正则表达式的字符串替换。
print(re.sub(r'\bROAD$', 'RD.', s)) # 打印: 100 NORTH MAIN RD.
## subn() 与 sub() 作用一样,但返回的是包含新字符串和替换执行次数的两元组。
print(re.subn(r'\bROAD$', 'RD.', s)) # 打印: ('100 NORTH MAIN RD.', 1)
# 字符串分割, split()
# 在正则表达式匹配的地方将字符串分片,将返回列表。只支持空白符和固定字符串。可指定最大分割次数,不指定将全部分割。
print(re.split(r'\s+', 'this is a test')) # 打印: ['this', 'is', 'a', 'test']
print(re.split(r'\W+', 'This is a test.', 2)) # 指定分割次数,打印:['this', 'is', 'a test']
# 如果你不仅对定界符之间的文本感兴趣,也需要知道定界符是什么。在 RE 中使用捕获括号,就会同时传回他们的值。
print(re.split(r'(\W+)', 'This is a test.', 2)) # 捕获定界符,打印:['this', ' ', 'is', ' ', 'a test']
## `MatchObject` 实例的几个方法
r=re.search(r'\bR(OA)(D)\b', s)
print(rs()) # 返回一个包含字符串的元组,可用下标取元组的内容,打印: ('OA', 'D')
print(r()) # 返回正则表达式匹配的字符串,打印: ROAD
print(r(2)) # 返回捕获组对应的内容(用数字指明第几个捕获组),打印: D
print(r.start()) # 返回匹配字符串开始的索引, 打印: 15
print(r.end()) # 返回匹配字符串结束的索引,打印: 19
print(r.span()) # 返回一个元组包含匹配字符串 (开始,结束) 的索引,打印: (15, 19)
# 匹配多个内容, findall() 返回一个匹配字符串行表
p=repile('\d+')
s0='12 drummers drumming, 11 pipers piping, 10 lords a-leaping'
print(p.findall(s0)) # 打印: [12, 11, 10]
print(re.findall(r'\d+', s0)) # 也可这样写,打印: [12, 11, 10]
# 匹配多个内容, finditer() 以迭代器返回
iterator=p.finditer(s0)
# iterator=re.finditer(r'\d+', s0) # 上句也可以这样写
for match in iterator:
print(match()) # 三次分别打印:12、 11、 10
# 记忆组
print(re.sub('([^aeiou])y$', 'ies', 'vacancy')) # 将匹配的最后两个字母替换掉,打印: vacanies
print(re.sub('([^aeiou])y$', r'\1ies', 'vacancy')) # 将匹配的最后一个字母替换掉,记忆住前一个(小括号那部分),打印: vacancies
print(re.search('([^aeiou])y$', 'vacancy')(1)) # 使用 group() 函数获取对应的记忆组内容,打印: c
# 记忆组(匹配重复字符串)
p=repile(r'(?P\b\w+)\s+\1') # 注意, re.match() 函数不能这样用,会返回 None
p=p.search('Paris in the the spring')
# p=re.search(r'(?P\b\w+)\s+\1', 'Paris in the the spring') # 这一句可以替换上面两句
print(p()) # 返回正则表达式匹配的所有内容,打印: the the
print(ps()) # 返回一个包含字符串的元组,打印: ('the',)
# 捕获组
r=re.search(r'\bR(OA)(D)\b', s) # 如过能匹配到,返回一个 SRE_Match 类(正则表达式匹配对象);匹配不到则返回“None”
# `MatchObject` 实例的几个方法
if r: # 如果匹配不到,则 r 为 None,直接执行下面语句则会报错;这里先判断一下,避免这错误
print(rs()) # 返回一个包含字符串的元组,可用下标取元组的内容,打印: ('OA', 'D')
print(r()) # 返回正则表达式匹配的字符串,打印: ROAD
print(r(2)) # 返回捕获组对应的内容(用数字指明第几个捕获组),打印: D
# 无捕获组
print(re.match("([abc])+", "abcdefab")s()) # 正常捕获的结果: ('c',)
print(re.match("(?:[abc])+", "abcdefab")s()) # 无捕获组的结果: ()
# 命名组
m=re.match(r'(?P\b\w+\b) *(?P\b\w+\b)', 'Lots of punctuation')
print(ms()) # 返回正则表达式匹配的所有内容,打印:('Lots', 'of')
print(m(1)) # 通过数字得到对应组的信息,打印: Lots
print(m('word2')) # 通过名称得到对应组的信息,打印: of
# 命名组 逆向引用
p=repile(r'(?P\b\w+)\s+(?P=word)') # 与记忆组一样用法, re.match() 函数同样不能这样用,会返回 None
p=p.search('Paris in the the spring') # r'(?P\b\w+)\s+(?P=word)' 与 r'(?P\b\w+)\s+\1' 效果一样
print(p()) # 返回正则表达式匹配的所有内容,打印: the the
print(ps()) # 返回一个包含字符串的元组,打印: ('the',)
# 使用松散正则表达式,以判断罗马数字为例
pattern='''
^ # beginning of string
(M{0,3}) # thousands - 0 to 3 Ms
(CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 Cs),
# or 500-800 (D, followed by 0 to 3 Cs)
(XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 Xs),
# or 50-80 (L, followed by 0 to 3 Xs)
(IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 Is),
# or 5-8 (V, followed by 0 to 3 Is)
$ # end of string
'''
print(re.search(pattern, 'M')) # 这个没有申明为松散正则表达式,按普通的来处理了,打印: None
print(re.search(pattern, 'M', re.VERBOSE)s()) # 打印: ('M', '', '', '')
# (?iLmsux) 用法
# 以下这三句的写法都是一样的效果,表示忽略大小写,打印: ['aa', 'AA']
print(re.findall(r'(?i)(aa)', 'aa kkAAK s'))
print(re.findall(r'(aa)', 'aa kkAAK s', re.I))
print(re.findall(r'(aa)', 'aa kkAAK s', re.IGNORECASE))
# 可以多种模式同时生效
print(re.findall(r'(?im)(aa)', 'aa kkAAK s')) # 直接在正则表达式里面写
print(re.findall(r'(aa)', 'aa kkAAK s', re.I | re.M)) # 在参数里面写
print(re.findall(r'(aa)', 'aa kkAAK s', re.I or re.M))
# 预编译正则表达式解析的写法
# romPattern=repile(pattern) # 如果不是松散正则表达式,则这样写,即少写 re.VERBOSE 参数
romPattern=repile(pattern, re.VERBOSE)
print(romPattern.search('MCMLXXXIX')s()) # 打印: ('M', 'CM', 'LXXX', 'IX')
print(romPattern.search('MMMDCCCLXXXVIII')s()) # 打印: ('MMM', 'DCCC', 'LXXX', 'VIII')
# match()、search()、sub()、findall() 等等都可以这样用