正则表达式是一个特殊的字符序列,它能帮助我们方便的检查一个字符串是否与某种模式匹配。Python提供Perl 风格的正则表达式模式。
re 模块使 Python 语言拥有全部的正则表达式功能。
1、字符元素(可跳过)
字符的匹配元素,比较琐碎,简单了解后即可,后期边用边查就记住了。
^匹配字符串的开头$匹配字符串的末尾。.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。[...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'[^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。re*匹配0个或多个的表达式。re+匹配1个或多个的表达式。re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式re{ n}匹配n个前面表达式。例如,"o{2}"不能匹配"god"中的"o",但是能匹配"good"中的两个o。re{ n,}精确匹配n个前面表达式。例如,"o{2,}"不能匹配"god"中的"o",但能匹配"gooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式a| b匹配a或b(re)匹配括号内的表达式,也表示一个组(?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。(?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。(?: re)类似 (...), 但是不表示一个组(?imx: re)在括号中使用i, m, 或 x 可选标志(?-imx: re)在括号中不使用i, m, 或 x 可选标志(?#...)注释.(?= re)前向肯定界定符。(?! re)前向否定界定符。(?> re)匹配的独立模式,省去回溯。w匹配数字字母下划线W匹配非数字字母下划线s匹配任意空白字符,等价于 [f]。S匹配任意非空字符d匹配任意数字,等价于 [0-9]。D匹配任意非数字A匹配字符串开始Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。z匹配字符串结束G匹配最后匹配完成的位置。b匹配一个单词边界,也就是指单词和空格间的位置。B匹配非单词边界。, , 等。匹配一个换行符。匹配一个制表符, 等1...9匹配第n个分组的内容。10匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。
2、flags标志位
用于控制正则表达式的匹配方式,其常用枚举类型解析如下
re.I:使匹配对大小写不敏感re.M:多行匹配,影响 ^ 和 $re.S:使 . 匹配包括换行在内的所有字符re.U:根据Unicode字符集解析字符。这个标志影响 w, W, b, B.
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回None。
def match(pattern, string, flags=0)
参数说明:
pattern->匹配的正则表达式
string->要匹配的字符串
flags标志位,上文有对应说明
示例:
import reprint('在起始位置匹配',re.match('hello', 'hello world',re.I))print('不在起始位置匹配',re.match('world', 'hello world',re.I))
输出:
在起始位置匹配 不在起始位置匹配 None
re.Match对象的span(),group(),groups()方法
import reprint("在hello在母串的起止位置索引",re.match('hello', 'hello world',re.I).span()) print("在hello在母串的起位置索引",re.match('hello', 'hello world',re.I).start()) print("在hello在母串的止位置索引",re.match('hello', 'hello world',re.I).end()) line = "dog eat my homework"# .* 表示任意匹配除换行符(、)之外的任何单个或多个字符# 多个flags可以用|链接matchobj = re.match( r'(.*) eat (.*)', line, re.M|re.I)print ("默认group(num=0)全部,matchobj.group() : ", matchobj.group())print ("小组1,matchobj.group(1) : ", matchobj.group(1))print ("小组2,matchobj.group(2) : ", matchobj.group(2))print ("小组1,2的tuple,matchobj.group(1,2) : ", matchobj.group(1,2))print ("全部分组的tuple,matchobj.groups() : ", matchobj.groups())
输出结果:
在hello在母串的起止位置索引 (0, 5)在hello在母串的起位置索引 0在hello在母串的止位置索引 5默认group(num=0)全部,matchobj.group() : dog eat my homework小组1,matchobj.group(1) : dog小组2,matchobj.group(2) : my homework小组1,2的tuple,matchobj.group(1,2) : ('dog', 'my homework')全部分组的tuple,matchobj.groups() : ('dog', 'my homework')
re.search 扫描整个字符串并返回第一个成功的匹配。
def search(pattern, string, flags=0)
search和match的区别主要在于是否第一个匹配
import reprint('在起始位置匹配',re.search('hello', 'hello world',re.I).span())print('不在起始位置匹配',re.search('world', 'hello world',re.I).span())matchobj=re.search('(world)', 'hello world',re.I)print('matchobj对象',matchobj)print('matchobj对象的groups方法',matchobj.groups())print('不存在',re.search('dog', 'hello world',re.I))
在起始位置匹配 (0, 5)不在起始位置匹配 (6, 11)matchobj对象 matchobj对象的groups方法 ('world',)不存在 None
Python 的re模块提供了re.sub用于替换字符串中的匹配项。
def sub(pattern, repl, string, count=0, flags=0)
参数解析:
pattern : 正则中的模式字符串。repl : 替换的字符串,也可为一个函数。string : 要被查找替换的原始字符串。count : 模式匹配后替换的最大次数,0 表示替换所有的匹配。flags : 编译时用的匹配模式,上文已做说明。
代码举例:
import re lie = "2 dogs eat my homework ;说谎"# 删除注释text = re.sub(r';.*$', "", lie)print ("正文 : ", text) # 移除空格text = re.sub(r' ', "", text)print ("移除空格 : ", text)
正文 : 2 dogs eat my homework 移除空格 : 2dogseatmyhomework
repl参数是一个函数的情况:
import re lie = "2 dogs eat my homework ;说谎"#匹配数量乘以100def multi(matched): value = int(matched.group(1)) return str(value * 100)text = re.sub(r'(d)', multi, lie)print ("匹配数量乘以100 : ", text)
匹配数量乘以100 : 200 dogs eat my homework ;说谎
match 和 search 是匹配一次 ,而findall 匹配所有并返回一个列表list,如果没有找到匹配的,则返回空列表。
def findall(pattern, string, flags=0)
代码示例:
import re lie = "OMG,2 dogs eat my homework ;说谎"#取非空字符串text = re.findall(r'S+', lie,re.I)print ("正文1 : ", text)#取cat字符串text = re.findall(r'cat', lie,re.I)print ("正文2 : ", text)
正文1 : ['OMG,2', 'dogs', 'eat', 'my', 'homework', ';说谎']正文2 : []
与findall 类似,但它返回的是一个迭代器。
def finditer(pattern, string, flags=0)
代码示例:
import re nums = re.finditer(r"d+","OMG,2 dogs eat my homework in 1 day ;说谎") for match in nums: print (match,match.group() )
2 1
split 按照能够匹配的子串将母串分割后返回列表
import re li=re.split(' ', 'OMG,2 dogs eat my homework in 1 day ;说谎')print("返回成功的list",li)li=re.split('cat', 'OMG,2 dogs eat my homework in 1 day ;说谎')print("没有分割的list",li)
返回成功的list ['OMG,2', 'dogs', 'eat', 'my', 'homework', 'in', '1', 'day', ';说谎']没有分割的list ['OMG,2 dogs eat my homework in 1 day ;说谎']
compile可以理解为正则的编译函数,生成一个表达式对象,供上述函数使用。
def compile(pattern, flags=0) #pattern : 一个字符串形式的正则表达式
pattern=re.compile(pattern, flags=0),返回编译对象
常用具体方法:
matchobj=pattern.match(母串,开始位置索引,结束位置索引)
matchobj=pattern.search(母串,开始位置索引,结束位置索引)
# match 和 search 是匹配一次,而 findall 匹配所有,返回list,若没有发现则返回[]
list=pattern.findall(母串,开始位置索引,结束位置索引)
# findall 和 finditer都是匹配所有,但finditer返回的是一个迭代器
iter=pattern.finditer(母串,开始位置索引,结束位置索引)
# 使用正则分割字符串
list=pattern.split(母串)
由于match和search类似,这里只用match示例:
import re lie = "OMG,2 dogs eat my homework ;说谎"pattern = re.compile(r'd+')print('pattern',pattern)print('查找头部,没有匹配',pattern.match(lie))print('从G,没有匹配',pattern.match(lie,2,5))matchobj=pattern.match(lie,4,10)print('从2,匹配',matchobj)print('matchobj的span方法',matchobj.span())
pattern re.compile('d+')查找头部,没有匹配 None从G,没有匹配 None从2,匹配 matchobj的span方法 (4, 5)
pattern.match返回为Match的对象,后续可以使用其span,group,groups,start,end等方法。
findall的示例
import re lie = "OMG,2 dogs eat my homework ;说谎"pattern = re.compile(r'd+')patternno = re.compile(r'cat')print('pattern',pattern)print('全局有匹配',pattern.findall(lie))print('全局无匹配',patternno.findall(lie))
pattern re.compile('d+')全局有匹配 ['2']全局无匹配 []
finditer示例
import re lie = "OMG,2 dogs eat my homework ;说谎"pattern = re.compile(r'd+')patternno = re.compile(r'cat')print('pattern',pattern)print('全局有匹配',[a.group() for a in pattern.finditer(lie)])print('全局无匹配',[a.group() for a in patternno.finditer(lie)])
pattern re.compile('d+')全局有匹配 ['2']全局无匹配 []
split示例
import re lie = "OMG,2 dogs eat my homework ;说谎"pattern = re.compile(r' ')patternno = re.compile(r'cat')print('pattern',pattern)print('匹配分割',pattern.split(lie))print('无匹配分割时,原样返回',patternno.split(lie))
pattern re.compile(' ')匹配分割 ['OMG,2', 'dogs', 'eat', 'my', 'homework', ';说谎']无匹配分割时,原样返回 ['OMG,2 dogs eat my homework ;说谎']