一、概述
1、概念
- Regular Expression
- 一种文本模式,描述在搜索文本时要匹配的一个或多个字符串
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
2、典型场景
3、语法
字面值
普通字符
需转义
^
$
.
|
?
*
+
()
[]
{}
元字符
4、匹配
单字,预定义元字符
- 除
外的所有字符 .
- 数字,等同于[0-9] d
- 非数字,等同于[^0-9] D
- 空白字符 [
f v] s
- 非空白字符 [^
f v] S
- 字母数字字符 [a-z A-Z 0-9 _ ] w
- 非字母数字字符 [^a-z A-Z 0-9 _ ] W
批量备选 或( | ) , 如yes|no
量词(控制 "字符、元字符,字符集" 如何重复)
- 0或1次 ?
- 0次或多次 *
- 1次或多次 +
- 特定
- 范围次数{n,m}
- n次{n}
- 至少n次{n,}
- 至多m次{,m}
贪婪与非贪婪
贪婪(默认):尽量匹配最大范围结果
非贪婪:尽量匹配最小的范围结果
边界匹配
- 行首 ^
- 行尾 $
- 单词边界
- 非单词边界 B
- 输入的开头 A
- 输入的结尾
- 注:可能会由于上下文不同而有所差异
二、Python 正则
模块
RegexObject 正则对象
1、模式对象,表现编译后的正则表达式(编译为字节码并缓存)
2、编译
3、.findall()
import re
text = "Tom is 8 years old. Mike is 34 years old."
pattern = re.compile('d+') #数字,等同于[0-9] d,1次或多次 +
pattern.findall(text) #开发的方法
re.findall('d+', text) #这种实现也可以,实际开发常用第一种,后面的参数是指明在哪寻找
['8', '34']
['8', '34']
import re
s = '\author:Tom'
pattern = re.compile('\\author') #第一种查找有转义符的方式
pattern.findall(s)
pattern = re.compile(r'\author')#第二种查找转义符的方式
pattern.findall(s)
['\author']
['\author']
4、.match(string[,pos[,endpos]])
import re
text = 'Tom is 8 years old. Mike is 34 years old.Peter is 87 years old.'
p_name = re.compile(r'[A-Z]w+') #字母数字字符 [a-z A-Z 0-9 _ ] w,1次或多次 +
p_name.findall(text)
['Tom', 'Mike', 'Peter']
import re
pattern = re.compile(r'<html>')
text = '<html><head></head><body></body></html>'
pattern.match(text) #返回MatchObject对象
text2 = ' <html><head></head><body></body></html>'
pattern.match(text2, 1) #match只从开始的位置开始匹配,字符串前面有空格就不行,返回空,要设置了开始匹配的位置,就能顺利返回查找对象
<re.Match object; span=(0, 6), match='<html>'>
<re.Match object; span=(1, 7), match='<html>'>
5、.search(string[,[pos[,endpos]]])
text2 = ' <html><head></head><body></body></html>'
pattern.search(text2) #不管什么位置都能查找
<re.Match object; span=(1, 7), match='<html>'>
import re
text = 'Tom is 8 years old. Mike is 34 years old.Peter is 87 years old.'
p1 = re.compile(r'd+')
p2 = re.compile(r'[A-Z]w+')
it = p1.finditer(text)
for m in it:
print(m) #返回每个查找到对象的起始与终止,还有对象
<re.Match object; span=(7, 8), match='8'>
<re.Match object; span=(28, 30), match='34'>
<re.Match object; span=(50, 52), match='87'>
MatchObject 匹配对象
1、表现被匹配的对象
2、 .group()
- 参数为0或空返回整个匹配
- 有参时返回特定分组匹配细节
- 参数也可以是分组名称
import re
text = 'Tom is 8 years old. Jerry is 34 years old.'
pattern = re.compile(r'(d+).*?(d+)')
m = pattern.search(text)
m.group()
m.group(1) #方法里面的参数,0表示整体,1表示第一个对象,2表示第二个对象
'8 years old. Jerry is 34'
'8'
import re
pattern = re.compile(r'(w+) (w+)') #注意中间有空格
text = 'Beautiful is better than ugly.'
it = pattern.finditer(text)
for m in it:
print(m.group())
Beautiful is
better than
3、.groups()
m.groups()
('8', '34')
4、.start()
m.start(1) #返回找到的第一个对象在元字符串的索引下标
7
5、.end()
m.end(1) #返回查到的第一个对象终止的下标,在这里也就是数字8后面的空格的索引
8
6、.span()
7、.groupdict()
Group 编组
1、场景
import re
re.search(r'ab+c', 'ababc')
re.search(r'(ab)+c', 'ababc')
<re.Match object; span=(2, 5), match='abc'>
<re.Match object; span=(0, 5), match='ababc'>
re.search(r'Center|re', 'Center')
re.search(r'Center|re', 'Centre')
re.search(r'Cent(er|re)', 'Centre')
re.search(r'Cent(er|re)', 'Center')
<re.Match object; span=(0, 6), match='Center'>
<re.Match object; span=(4, 6), match='re'>
<re.Match object; span=(0, 6), match='Centre'>
<re.Match object; span=(0, 6), match='Center'>
re.search(r'(w+) 1', 'hello hello worlds')
import re
text = "Tom:98"
pattern = re.compile(r'(w+):(d+)')
m = pattern.search(text)
m.group()
m.groups()
m.group(1)
'Tom:98'
('Tom', '98')
'Tom'
2、声明
3、引用
- 匹配对象内 m.group(‘name’)
- 模式内 (?P=name)
- 表现内 g
pattern = re.compile(r'(?P<name>w+):(?P<score>d+)')
m = pattern.search(text)
m.group()
m.group('name')
m.group('score')
'Tom:98'
'Tom'
'98'
应用
1、字符串操作
- .split(string,maxsplit=0)
分割字符串,使用编组不会删除分割内容
import re
text = 'Beautiful is better ugly.
Explicit is better than implicit.
Simple is better than complex.'
p = re.compile(r'
')
p.split(text)
re.split(r'
', text, 1)
['Beautiful is better ugly.',
'Explicit is better than implicit.',
'Simple is better than complex.']
['Beautiful is better ugly.',
'Explicit is better than implicit.
Simple is better than complex.']
- .sub(repl,string,count=0)
替换字符串
import re
ords = 'ORD000
ORD001
ORD003'
re.sub(r"d+",'-', ords)
text = 'Beautiful is *better* ugly.'
re.sub(r'*(.*?)*','<strong>g<1></strong>', text)
re.sub(r'*(?P<html>.*?)*','<strong>g<html></strong>', text) #也可以使用这种方法
re.sub(r'([A-Z]+)(d+)','g<2>-g<1>', ords)
'ORD-
ORD-
ORD-'
'Beautiful is <strong>better</strong> ugly.'
'Beautiful is <strong>better</strong> ugly.'
'000-ORD
001-ORD
003-ORD'
- .subn(repl,string,count=0)
替换并返回替换数量
re.subn(r'([A-Z]+)(d+)','g<2>-g<1>', ords)
('000-ORD
001-ORD
003-ORD', 3)
2、编译标记
import re
text = 'Python python PYTHON'
re.search(r'python', text)
re.findall(r'python', text, re.I) #忽略大小写
['Python', 'python', 'PYTHON']
import re
re.findall(r'^<html>', '
<html>', re.M)
['<html>']
re.findall(r'd(.)','1
e',re.S)
['
']
3、模块级别操作
- 清理正则缓存 re.purge()
- 逃逸字符 re.escape()