Python 学习:正则表达式 - re
规则表达式(Regular Expression, RE),又称作正则表达式,通常用于检索和替换符合指定规则的文本,正则表达式定义的规则,称作模式(Pattern)。正则表达式的作用是从文本中查找到符合模式的文本,在Python中使用正则表达式,需要导入re模块。
import re
查看正则表达式的元字符,请参考文档:正则表达式 第一篇:元字符
一,re模块常用的函数
从帮助文档中可以看到,re模块导出的函数主要是:match、search、sub、split、findall、finditer、compile和escape,这些函数中,通常有三个参数,string:用于匹配的文本,pattern:正则表达式的模式,flags:匹配选项,flags 默认为0 ,不使用任何模式。
正则表达式的flag主要有:
- I:IGNORECASE, 忽略大小写的匹配模式
- M:MULTILINE,多行模式, 改变 ^ 和 $ 的行为
- S:DOTALL,此模式下 '.' 的匹配不受限制,可匹配任何字符,包括换行符
- X:VERBOSE,冗余模式, 此模式忽略正则表达式中的空白和#号的注释,例如写一个匹配邮箱的正则表达式
- U:UNICODE,使用 \w, \W, \b, \B 这些元字符时将按照 UNICODE 定义的属性.
正则表达式可以同时使用多个flag,在 Python 里面使用按位或运算符 | 同时添加多个fag,例如 re.compile('', re.I|re.M|re.S)
1,编译正则表达式
compile函数用于编译一个正则表达式对象,在符用正则表达式时,步需要重新编译:
re.compile(pattern, flags=0)
2,原始字符标记
原始字符串表示 r'regex',如果不使用r,正则表达式中的 元字符'\' 都必须进行转义:
>>> re.match(r"\W(.)\1\W", " ff ") >>> re.match("\\W(.)\\1\\W", " ff ")
这就意味着,在正则表达式中,如果 \x 是元字符,那么必需使用r'\x'。
如果要匹配到文本 '\' (也就是说,\ 不是元字符),那么必须在正则表达式中对其进行转义,使用原始字符标记,是r'\\';如果不使用原始字符标记,是'\\\\':
>>> re.match(r"\\", r"\\") >>> re.match("\\\\", r"\\")
3,拆分
把一个字符串,按照正则表达式匹配的结果进行拆分
text='foo bar\t baz \tqux' re.split(r'\s+',text)
或者,先编译成正则表达式对象,然后对字符串进行拆分:
regex=re.compile(r'\s+') text='foo bar\t baz \tqux' regex.split(text)
4,匹配第一个子串
正则表达式有两个匹配函数:match和search函数,这两个函数的相同之处:从字符串中查找可以匹配的子串,返回第一个匹配的子串,一旦匹配成功,就不再继续查找,并返回一个SRE_Match 对象;如果查找不到,则返回None。
re.match(pattern, string, flags=0)
re.search(pattern, string, flags=0)
不同之处在于:
- re.match函数从字符串的开头查找,如果开头不匹配,则不再继续查找,返回None;
- 而re.search匹配整个字符串,从字符串的任意位置开始匹配,直到找到第一个匹配(注意:仅仅是第一个)或者没有匹配到任何文本。
5,查找所有匹配的子串
re.findall在字符串中找到匹配正则表达式的所有文本,作为一个列表返回,如果没有找到匹配,则返回空列表:
re.findall(pattern, string, flags=0)
re.finditer在字符串中找到匹配正则表达式所的所有文本,并把它们作为一个迭代器返回:
re.finditer(pattern, string, flags=0)
6,替换匹配的字符
把正则表达式 pattern 匹配到的字符串替换为 repl 指定的字符串, 参数 count 用于指定最大替换次数,默认值是o,表示无限大。
re.sub(pattern, repl, string, count=0, flags=0)
替换函数可以把文本的标点符号和HTML标签去掉。在替换字符时,需要注意:如果repl参数中包含转义字符,会出现错误,例如,对于 re.sub('pattern',r'\w+',text), re会抛出错误:bad escape \w at position 0。
从re的手册《re — Regular expression operations》中,可以看到,在3.0以上版本,都会出现这个错误:
Changed in version 3.x : Unknown escapes in repl consisting of '\' and an ASCII letter now are errors.
二,re内置的对象
re模块内置的对象有Pattern对象和Match对象,一个用于表示已编译的正则表达式对象,一个表示search()和match()匹配的结果。
1,Pattern对象
Pattern对象是一个已编译的正则表达式对象,使用re.compile()进行构造,通过Pattern提供的一系列方法可以对文本进行匹配查找。
Pattern对象的方法,用于进行正则匹配:
- search(string[, pos[, endpos]])
- match(string[, pos[, endpos]])
- split(string, maxsplit=0)
- findall(string[, pos[, endpos]])
- finditer(string[, pos[, endpos]])
- sub(repl, string, count=0)
Pattern提供了几个可读属性用于获取表达式的相关信息:
- pattern: 编译时用的表达式字符串。
- flags: 编译时用的匹配模式,数字形式
- groups: 表达式中分组的数量。
- groupindex: 以表达式中有别名的组的别名为键、以该组对应的编号为值的字典,没有别名的组不包含在内。
2,Match对象
Match对象存储 re.match() 或 re.search()的结果,当匹配到文本时,含有为True的boolean值;当没有匹配到任何文本时,返回None。
def displaymatch(match): if match is None: return None return '<Match: %r, groups=%r>' % (match.group(), match.groups())
Match对象的属性:
- string:传递给re.match() 或 re.search()的文本
- regs:元组集合,表示每个匹配的起始索引和结束索引
- pos:正则表达式开始匹配的索引
- endpos:正则表达式结束匹配的索引
- re:正则表达式对象
Match对象的方法:
- start(group):group的默认值是0,表示每个匹配的文本的开始索引
- end(group):group的默认值是0,表示每个匹配的文本的结束索引
- group(group=0):参数为0时,表示返回整个匹配
- groups():返回匹配到的所有分组的索引
- span(group=0):返回匹配的开始索引和结束索引
三,正则表达式的应用
1,删除文本中的标点符号
remove_punct=re.compile('[%s]' % re.escape(string.punctuation)) no_punct = remove_punct.sub(u'', text)
2,删除文本中的HTML标签
# use sub to replace the tags pat = re.compile('<[^>]+>', re.S) pat.sub('', text) #combine the normal text pat = re.compile('>(.*?)<') ''.join(pat.findall(text))
3,查找匹配的文本
import re text_data = 'guru99@google.com, careerguru99@hotmail.com, users@yahoomail.com' emails_list = re.findall(r'[\w\.-]+@[\w\.-]+', text_data)
参考文档: