正则表达式语法
.
:默认是匹配除换行之外的所有字符;如果flag为re.S或re.DOALL,会匹配包含换行符的任意一个字符
^
: 匹配字符串的开始位置,在多行模式下(指定flag为re.M或re.MULTILINE)可以匹配每一行的开头
$
: 匹配字符串的结束位置,同 ^
一样,默认只匹配一行,在re.M或re.MULTILINE 下可以匹配多行
*
: 匹配0次,1次或多次前面出现的字符
+
: 匹配一次或多次前面出现的字符
?
: 这个符号有两个用途:
- 匹配0次或一次前面出现的字符
- 默认情况下,*, +, ?这三个符号是贪婪匹配,在后面加?之后就是非贪婪匹配
{m}
:精确匹配m个前面的字符,前面的字符大于m也是匹配不到的。(re.match会失败,但re.search还是可以)
{m, n}
: 匹配m到n个前面出现的字符。如果省略n,即{m, }
会指定一个无上限的上边界,如:a{4}b
会匹配到字符串"aaaab"
,也会匹配“aaaaab"
(只要前面的字符大于等于m就可以匹配到), 但不会匹配”aaab"
{m, n}?
:非贪婪匹配,如 r’a{2,4}b’ 匹配字符串 ‘aaaab’ 会匹配到完整的 aaaab,但r’a{2,4}?b’ 会匹配到 ’aab‘ 官方文档是这么解释的,但实际验证两种方式结果一样
[]
: 一个字符集
- 字符集合
- 用-指定范围的,如[a-zA-Z], 指定从a到z,A到Z这个范围的字符都匹配
|
: A|B,匹配A或B
分组
- 扩展表示法都是以
?
开始,通常是用于在判断匹配之前提供标记,实现一个 前视匹配或条件检查 - 尽管也是用(),但只有(?P)表示一个匹配分组,其他都没有创建一个分组
- 使用"(xx)“捕获组时,如果存在”(xx(xx)xx)"情况,里面的捕获号次于外侧捕获号
(...)
:指定一个捕获组
(?:...)
:指定一个非捕获组,即只做匹配不捕获结果,也不分配组号,适用于match对象和正则表达式对象
(?P=name)
/ (?P<name>)
:可以指定匹配组的别名,用 group('name')
可以访问
(?aiLmsux)
: 不匹配任何字符串,相当于re.A/re.I/re.L/re.M/re.S/re.U/re.X; 比如指定(?i)xxx,表示匹配时不区分大小写;如果想在正则表达式而不是re.compile中指定标记,这是种好方式
(?#...)
:不做匹配,只作为注释
(?=...)
: 如果一个字符串后面跟着…才匹配
(?!...)
:如果一个字符串后面不跟…才匹配
(?<=...)
:如果一个字符串前面为…才匹配
(?<!...)
:如果一个字符串前面不为…才匹配
(?(id/name)yes-pat|no-pat)
:如果一个匹配组id或name存在则与yes-pat匹配,否则与no-pat匹配
\number
: 代表第几个匹配组。匹配组是从1开始的
r'(^\s*(\w+)(::)?(?(3)\2|)'
# 如果匹配组3(::)存在,则为匹配组2(\w+),否则为空
\A
: 只匹配字符串的开头
\b
:
\B
:
\d
/ \D
: 匹配任意一个十进制数; 匹配除十进制数之外的任意一个其他字符
\s
/ \S
:匹配任何空格字符(包括\n:换行,\t:); 匹配除空白字符之外的任意一个字符
\w
/ \W
:Unicode下能匹配数字,字母,下划线,还能匹配汉字等其他语言的字母,但不能匹配标点如’;', 也不能匹配注释符\也不匹配空格等,如果设置了是ASCII只匹配大小写字母和数字,与相反
\Z
:
flags
re.A
/ re.ASCII
:只匹配ASCII字符
re.I
/ re.IGNORECASE
:不区分大小写,这两种形式都可以
re.S
/ re.DOTALL
:这个标志可以让”.“匹配任何字符包括换行符,主要也就是用来匹配换行符”\n“的
re.M
/ re.MULTILINE
: 可以匹配多行
re.L
/ re.LOCALE
:
re.DEBUG
: debug信息
re.X
/ re.VERBOSE
:
需要转义的特殊字符:+;*
函数
编译
compile(pattern, flags=0):编译正则表达式的模式,返回一个正则表达式对象。推荐使用预编译成正则表达式对象再进行操作。但预编译并不是必须的,如果需要编译就使用编译过的方法,如果不需要就是用函数,函数名和方法名是相同的
搜索
match(pattern, string, flags=0)
:从字符串的开头找到匹配项,只匹配开头,后面即使有也不匹配,匹配成功返回match对象,匹配不到返回None;即使是指定了 re.MULTILINE 模式,match也只匹配字符串开头而非每一行的开头
# 以下匹配成功,输出match对象
re.match(r'\w+', 'hello123=@')
<re.Match object; span=(0, 8), match='hello123'>
# 字符串不以字母数字下划线开头则没有输出,匹配失败,输出为空
re.match(r'\w+', '\(\)hello123=@')
search(pattern, string, flags=0)
:查找模式,不但搜索模式在字符串中第一次出现的位置,而且严格地对字符串从左到右搜索,匹配到之后返回match对象,匹配不到返回None。注意:这个方法从左到右只搜索第一个匹配到的地方后就不会往后搜索了
# 上述第二个例子使用search返回match对象
>> re.search(r'\w+', '\(\)hello123=@')
<re.Match object; span=(4, 12), match='hello123'>
fullmatch(pattern, string, flags=0)
:和match,search都不同, 只有整个字符串都匹配会返回match对象,否则返回None。
>> re.fullmatch(r'\w+', 'hello123=@') # 返回None
>> re.fullmatch(r'\w+=@', 'hello123=@') # 返回match对象
<re.Match object; span=(0, 10), match='hello123=@'>
分隔
split(pattern,string,maxsplit=0,flag=0)
:根据pattern指定的模式分解string,返回一个由分隔的各部分字符串组成的列表。如果使用了捕获组,捕获组字符串也是作为列表中的元素出现。maxsplit是分隔次数,如果maxsplit非0,则最多分隔maxsplit次,剩余的字符串整体作为列表中的一个元素。
>> re.split(r'\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>> re.split(r'(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '']
>> re.split(r'\W+', 'Words, words, words.', 1)
['Words', 'words, words,']
- 其他情况补充
查找
findall(pattern, string, flags=0)
:从左到右扫描string并按查找到的顺序以列表的形式返回结果。不同于match或search的是,这个方法会遍历整个字符串,查找所有匹配pattern的所有字符串
返回元组列表,元组中包含匹配到的字符串
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') # 没有捕获组,返回所有匹配到的字符串列表
['foot', 'fell', 'fastest']
>>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10') # 两个捕获组,返回元组列表
[('width', '20'), ('height', '10')]
>>> re.findall(r'(\w+)', 'set width=20 and height=10') # 一个捕获组,返回字符串列表
['set', 'width', '20', 'and', 'height', '10']
finditer(pattern, string, flags=0)
:同findall一样,从左到右扫描字符串并按顺序找到匹配的内容,返回match对象的迭代器,以迭代的方式返回匹配对象:注意返回的是match对象
替换
sub(pattern, repl, string, count=0, flags=0)
:在string中把pattern模式替换为repl,返回替换后的字符串,原string不变
对于更复杂的情况,可以将第二个参数替换为一个回调函数,该函数返回一个用来替换的字符串,入参是一个匹配对象
subn()
: 和sub一样,但还返回一个表示替换的总数,替换后的字符串和表示替换总数的数字作为一个拥有两个元素的元组返回
现在有个问题:怎样替换多个正则表达式对象?
正则表达式对象
经过compile编译之后的正则表达式对象除了上述方法外,还有以下方法或属性:
Pattern.flags
Pattern.groups
:捕获组数量Pattern.groups
Pattern.groupindex
Pattern.pattern
match对象
search或match方法返回的对象
Match.expand
:
Match.group([group1, ...])
:返回一个元组,要么返回整个匹配对象(参数为0或没有,没有默认为0),要么根据要求返回特定子组(参数可为多个),子组是从1开始的,返回的是捕获组的内容,如果匹配不到返回为None;如果是指定命名组名称,可以将名称字符串作为group的参数返回对应的键值;异常:IndexError
Match.__getitem__(g)
:
Match.groups(default=None)
:返回一个包含唯一或全部子组的元组。只匹配子组,如果没有子组,group()仍然返回整个匹配时,但groups返回一个空元组
Match.groupdict(default=None)
:返回一个以名字命名的子组的字典。返回所有匹配到的字典,这个方法貌似只用在使用 ?P 指定子组名字的对象
Match.start([group])/Match.end([group])
:
Match.span([group])
:
Match.pos
:
Match.endpos
:
Match.lastindex
:
Match.lastgroup
:
Match.re
:
Match.string
: