目录
- re模块使用
- 1. 编译正则表达式对象
- 2. 搜索 re.search(pattern, string, flags=0)
- 3. 匹配 re.match(pattern, string, flags=0)
- 4. 全匹配 re.fullmatch(pattern, string, flags=0)
- 5. 分割 re.split(pattern, string, maxsplit=0, flags=0)
- 6. 全找 re.findall(pattern, string, flags=0)
- 7. 全找 re.finditer(pattern, string, flags=0)
- 8. 替换 re.sub(pattern, repl, string, count=0, flags=0)
- 9. 替换 re.subn(pattern, repl, string, count=0, flags=0)
- 10. 转义 re.escape(pattern)
- 11. 清除 re.purge()
- 匹配对象
- 正则表达式对象
- 第三方模块
本文只介绍Python中re模块于正则表达式中的应用。正则表达式的相关知识,请参考其它文章。
re模块使用
1. 编译正则表达式对象
# -*- coding: utf-8 -*-
import re
reObj = re.compile(r'\d+', flags=0)
# reObj是正则表达式对象,通过该对象可以进行正则表达式的各种操作(这一节只讲re模块的操作)
# 第一个参数:指定要匹配的正则表达式
# 第二个参数:指定匹配时的规则。(re模块的其它函数也会用到该参数)如下:
# re.A:只匹配ASCII,而不是Unicode。这只对Unicode样式有效,会被byte样式忽略。
# re.DEBUG:显示编译时的debug信息,没有内联标记。
# re.I:进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。
# re.L:由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配。这个标记只能对byte样式有效。这个标记不推荐使用,因为语言区域机制很不可靠。
# re.M:设置以后,样式字符 '^' 匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号);样式字符 '$' 匹配字符串尾,和每一行的结尾(换行符前面那个符号)。
# re.S:让 '.' 特殊字符匹配任何字符,包括换行符;如果没有这个标记,'.' 就匹配 除了 换行符的其他任意字符。
# re.X:这个标记允许你编写更具可读性更友好的正则表达式。例:
a = re.compile(r"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits""", re.X)
2. 搜索 re.search(pattern, string, flags=0)
扫描整个字符串找到匹配样式的第一个位置,并返回一个相应的匹配对象。如果没有匹配,就返回一个 None 。
# -*- coding: utf-8 -*-
import re
matchObj = re.search(r'\d+', 'ab123c456')
print(matchObj)
# 输出:<re.Match object; span=(2, 5), match='123'>
3. 匹配 re.match(pattern, string, flags=0)
如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的匹配对象 。 如果没有匹配,就返回 None。
# -*- coding: utf-8 -*-
import re
matchObj = re.match(r'\d+', 'ab123c456')
print(matchObj)
# 输出:None
matchObj = re.match(r'\d+', '0ab123c456')
print(matchObj)
# 输出:<re.Match object; span=(0, 1), match='0'>
4. 全匹配 re.fullmatch(pattern, string, flags=0)
如果整个 string 匹配到正则表达式样式,就返回一个相应的匹配对象 。 否则就返回一个 None。
# -*- coding: utf-8 -*-
import re
matchObj = re.fullmatch(r'\d+', 'ab123c456')
print(matchObj)
# 输出:None
matchObj = re.fullmatch(r'\d+', '0123456')
print(matchObj)
# 输出:<re.Match object; span=(0, 7), match='0123456'>
5. 分割 re.split(pattern, string, maxsplit=0, flags=0)
用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。
# -*- coding: utf-8 -*-
import re
result = re.split(r'\d+', 'a123c456d')
print(result)
# 输出:['a', 'c', 'd']
result = re.split(r'(\d+)', 'a123c456d')
print(result)
# 输出:['a', '123', 'c', '456', 'd']
result = re.split(r'\d+', 'a123c456d', 1)
print(result)
# 输出:['a', 'c456d']
# 如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。结尾也一样。
result = re.split(r'\d+', '0a123c456d7')
print(result)
# 输出:['', 'a', 'c', 'd', '']
6. 全找 re.findall(pattern, string, flags=0)
对 string 返回一个不重复的 pattern 的匹配列表, string 从左到右进行扫描,匹配按找到的顺序返回。
# -*- coding: utf-8 -*-
import re
result = re.findall(r'\d+', 'a123c456d')
print(result)
# 输出:['123', '456']
result = re.findall(r'\d+', 'abcdefghi')
print(result)
# 输出:[]
7. 全找 re.finditer(pattern, string, flags=0)
pattern 在 string 里所有的非重复匹配,返回为一个迭代器 iterator 保存了 匹配对象 。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。
# -*- coding: utf-8 -*-
import re
result = re.finditer(r'\d+', 'a123c456d')
print(result)
# 输出:<callable_iterator object at 0x00000000022003C8>
for itm in result:
print(itm)
# 输出1:<re.Match object; span=(1, 4), match='123'>
# 输出2:<re.Match object; span=(5, 8), match='456'>
result = re.finditer(r'\d+', 'abcdefghi')
print(result)
# 输出:<callable_iterator object at 0x00000000028FFCC0>
for itm in result:
print(itm)
# 输出:因为result没有匹配到任何内容,所以无输出
8. 替换 re.sub(pattern, repl, string, count=0, flags=0)
返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。
# -*- coding: utf-8 -*-
import re
result = re.sub(r'a(\d+)', r'digital\1', 'a1 a2')
print(result)
# 输出:digital1 digital2
如果 repl 是一个函数,那它会对每个非重复的 pattern 的情况调用。这个函数只能有一个 匹配对象 参数,并返回一个替换后的字符串。
# -*- coding: utf-8 -*-
import re
def dash_repl(matchObj):
return '-'
result = re.sub(r'-{2}', dash_repl, 'a--b--c')
print(result)
# 输出:a-b-c
9. 替换 re.subn(pattern, repl, string, count=0, flags=0)
行为与 sub() 相同,但是返回一个元组 (字符串, 替换次数).
# -*- coding: utf-8 -*-
import re
result = re.subn(r'-{2}', r'-', 'a--b--c')
print(result)
# 输出:('a-b-c', 2)
result = re.subn(r'-{2}', r'-', 'a--b--c', 1)
print(result)
# 输出:('a-b--c', 1)
result = re.subn(r'-{3}', r'-', 'a--b--c')
print(result)
# 输出:('a--b--c', 0)
10. 转义 re.escape(pattern)
转义 pattern 中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的。
# -*- coding: utf-8 -*-
import re
print(re.escape('python.exe'))
# 输出:python\.exe
operators = ['+', '-', '*', '/', '**']
print('|'.join(map(re.escape, operators)))
# 输出:\+|\-|\*|/|\*\*
11. 清除 re.purge()
清除正则表达式缓存。
匹配对象
上面部分方法的返回值为匹配对象(形如:<re.Match object; span=(2, 5), match=‘123’>),现在来具体介绍下:
1. 子组 Match.group([group1, …])
返回一个或者多个匹配的子组。
# -*- coding: utf-8 -*-
import re
matchObj = re.search(r'(\d+)c(\d+)', 'ab123c456')
print(matchObj)
# 输出:<re.Match object; span=(2, 5), match='123'>
print(matchObj.group(0))
# 输出:123c456
print(matchObj.group(1))
# 输出:123
print(matchObj.group(2))
# 输出:456
print(matchObj.group(1, 2))
# 输出:('123', '456')
如果正则表达式使用了 (?P<name>…) 语法, groupN 参数就也可能是命名组合的名字:
# -*- coding: utf-8 -*-
import re
matchObj = re.search(r'(?P<first_name>\w+)\s+(?P<last_name>\w+)', 'Coder X')
print(matchObj.group(0))
# 输出:Coder X
print(matchObj.group('first_name'))
# 输出:Coder
print(matchObj.group('last_name'))
# 输出:X
如果一个组匹配成功多次,就只返回最后一个匹配:
# -*- coding: utf-8 -*-
import re
matchObj = re.search(r'(..)+', 'CoderXx')
print(matchObj.group(0))
# 输出:CoderX
print(matchObj.group(1))
# 输出:rX
2. 所有子组 Match.groups(default=None)
返回一个元组,包含所有匹配的子组:
# -*- coding: utf-8 -*-
import re
matchObj = re.search(r'(..)(..)(..)', 'CoderXx')
print(matchObj.groups())
# 输出:('Co', 'de', 'rX')
3. 所有子组 Match.groupdict(default=None)
返回一个字典,包含了所有的 命名子组:
# -*- coding: utf-8 -*-
import re
matchObj = re.search(r'(?P<first_name>\w+)\s+(?P<last_name>\w+)\s+(\w+)', 'Coder X other')
print(matchObj.groupdict())
# 输出:{'first_name': 'Coder', 'last_name': 'X'}
print(matchObj.groups())
# 输出:('Coder', 'X', 'other')
4. 匹配到的位置 Match.start([group]) Match.end([group])
返回 group 匹配到的字串的开始和结束标号:
# -*- coding: utf-8 -*-
import re
matchObj = re.search(r'(\d+)', 'a123b')
print(matchObj.start(), matchObj.end())
# 输出:1 4
5. 匹配到的位置 Match.span([group])
对于一个匹配 m , 返回一个二元组 (m.start(group), m.end(group)) :
# -*- coding: utf-8 -*-
import re
matchObj = re.search(r'(\d+)', 'a123b')
print(matchObj.span())
# 输出:(1, 4)
正则表达式对象
之前提到正则表达式对象就是re.compile(pattern, flags=0)方法的返回值。该对象支持的方法与re模块基本相同,差异如下:
- 方法由正则表达式对象直接调用;
- 方法里不用指定正则表达式,因为在编译时已经指定了;
- 部分方法可为匹配指定开始位置和结束位置。
一个简单的例子如下:
# -*- coding: utf-8 -*-
import re
reObj = re.compile(r'\d+')
matchObj = reObj.search('a123b')
print(matchObj.group())
# 输出:123
matchObj = reObj.search('a123b', 1, 2)
print(matchObj.group())
# 输出:1
第三方模块
第三方模块regex , 提供了与标准库 re 模块兼容的API接口, 同时还提供了额外的功能和更全面的Unicode支持。