Python正则表达式
re模块
re 模块使 Python 语言拥有全部的正则表达式功能。
import re
>>> for i in dir(re):print(i)
A
ASCII
DEBUG
DOTALL
I
IGNORECASE
L
LOCALE
M
MULTILINE
RegexFlag
S
Scanner
T
TEMPLATE
U
UNICODE
VERBOSE
X
compile用于编译正则表达式,生成一个正则表达式( Pattern )对象copyreg
enum
error
escape
findall在字符串中找到正则表达式所匹配的所有子串
finditer字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
fullmatch
functools
match尝试从字符串的起始位置匹配一个模式
purge
search扫描整个字符串并返回第一个成功的匹配
split 按照能够匹配的子串将字符串分割后返回列表
sre_compile
sre_parse
sub替换字符串中的匹配项
subn
template
compile 编译正则表达式,给其他函数使用
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象
给其它函数使用
语法:
re.compile(pattern[, flags])
pattern : 一个字符串形式的正则表达式
flags 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
- re.I 忽略大小写
- re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
- re.M 多行模式
- re.S 即为' . '并且包括换行符在内的任意字符(' . '不包括换行符)
- re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
- re.X 为了增加可读性,忽略空格和' # '后面的注释
>>> ok = re.compile('ok',re.I)
>>> ok
re.compile('ok', re.IGNORECASE)
>>> type(ok)
<class '_sre.SRE_Pattern'>
match 从字符串的起始位置匹配
re.match 尝试从字符串的起始位置匹配一个模式
匹配成功re.match方法返回一个匹配的对象
如果不是起始位置匹配成功的话,match()就返回none
语法:
re.match(pattern, string, flags=0)
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。
示例:
>>> match = re.match('www','www.baidu.com') #匹配成功re.match方法返回一个匹配的对象
>>> match
<_sre.SRE_Match object; span=(0, 3), match='www'>
>>> match.span()
(0, 3)
>>> match = re.match('com','www.baidu.com') #匹配不成功,返回None
>>> match
>>> print(match)
None
search扫描整个字符串并返回第一个成功的匹配的对象
re.search 扫描整个字符串并返回第一个成功的匹配。
匹配成功re.search方法返回一个匹配的对象,否则返回None。
语法:
re.search(pattern, string, flags=0)
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。
>>> match = re.search('www','www.baidu.com') #匹配成功,返回第一个成功的匹配
>>> match
<_sre.SRE_Match object; span=(0, 3), match='www'>
>>> match.span()
(0, 3)
>>> match = re.search('com','www.baidu.com')
>>> match
<_sre.SRE_Match object; span=(10, 13), match='com'>
>>> match.span()
(10, 13)
>>> match = re.search('cn','www.baidu.com') #匹配不成功,返回None
>>> match
>>> print(match)
None
findall在字符串中找到正则表达式所匹配的所有子串,返回一个列表
在字符串中找到正则表达式所匹配的所有子串
找到了就返回一个列表,
如果没有找到匹配的,则返回空列表。
match 和 search 是匹配一次 findall 匹配所有。
语法:
findall(pattern, string, flags=0)
pattern : 正则中的模式字符串。
string : 要被查找替换的原始字符串。
flags : 编译时用的匹配模式,数字形式。
>>> string = 'fan1 status OK\nfan2 status ok'
>>> patt = re.compile('(.*) status (.*)',re.I)
>>> match = re.findall(patt,string)
>>> match
[('fan1', 'OK'), ('fan2', 'ok')]
finditer在字符串中找到正则表达式所匹配的所有子串,返回迭代器
在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.finditer(pattern, string, flags=0)
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
split 按照能够匹配的子串将字符串分割后返回列表
split 方法按照能够匹配的子串将字符串分割后返回列表
语法:
re.split(pattern, string[, maxsplit=0, flags=0])
pattern 匹配的正则表达式
string 要匹配的字符串。
maxsplit 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。
>>> string = 'fan1 status OK'
>>> patt = re.compile('status',re.I)
>>> match = re.split(patt,string)
>>> match
['fan1 ', ' OK']
sub 替换字符串中的匹配项
re.sub用于替换字符串中的匹配项。
语法:
re.sub(pattern, repl, string, count=0, flags=0)
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
flags : 编译时用的匹配模式,数字形式。
匹配到的对象的方法
end 返回匹配结束的位置
endpos
expand
group 返回被 RE 匹配的字符串
groupdict
groups
lastgroup
lastindex
pos
re
regs
span 返回一个元组包含匹配 (开始,结束) 的位置
start 返回匹配开始的位置
string
start 返回匹配开始的位置
end 返回匹配结束的位置
span 返回一个元组包含匹配 (开始,结束) 的位置
import re #导入模块
>>> ok = re.compile('ok',re.I) #匹配模式
>>> string = 'fan1 status OK\nfan2 status ok' #字符串
>>> match = re.search(ok,string) #匹配方式
>>> match.start()
12
>>> match.end()
14
>>> match.span()
(12, 14)
group 返回被 RE 匹配的字符串
group([group1, ...]) -> str or tuple.
group() 同group(0)就是匹配正则表达式整体结果
group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分
>>> string = 'fan1 status OK\nfan2 status ok'
>>> patt = re.compile('(.*) status (.*)',re.I)
>>> patt
re.compile('(.*) status (.*)', re.IGNORECASE)
>>> match = re.search(patt,string)
>>> match
<_sre.SRE_Match object; span=(0, 14), match='fan1 status OK'>
>>> match.group()
'fan1 status OK'
>>> match.group(0)
'fan1 status OK'
>>> match.group(1)
'fan1'
>>> match.group(2)
'OK'
正则表达式
正则表达式是由普通字符以及特殊字符(称为"元字符")组成的文字模式。
普通字符
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。
- 可打印字符包括所有大写和小写字母[a-z,A-Z]、所有数字[0-9]、所有标点符号和一些其他符号。
- 不可打印字符
字符 | 描述 |
\cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
特殊字符(元字符)
所谓特殊字符,就是一些有特殊含义的字符
许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须转义,即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符:
特别字符 | 描述 |
. | 匹配除换行符(\n、\r)之外的任何单个字符。 要匹配包括 '\n' 在内的任何字符,请使用像"(.|\n)"的模式。 要匹配 . ,请使用 \. 。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。 |
| | 指明两项之间的一个选择。要匹配 |,请使用 \|。 |
次数限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。
正则表达式的限定符有:
字符 | 描述 |
* | 匹配前面的子表达式0次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。要匹配 * 字符,请使用 \*。 |
+ | 匹 配前面的子表达式1次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。要匹配 + 字符,请使用 \+。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。 例如,"do(es)?" 可以匹配 "do" 、 "does"。? 等价于 {0,1}。 要匹配 ? 字符,请使用 \?。 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 |
边界定位符
定位符使您能够将正则表达式固定到行首或行尾。
它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。
定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。
正则表达式的定位符有:
字符 | 描述 |
^ | 匹配输入字符串开始的位置。 如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n 或 \r 之后的位置匹配。 要匹配 ^ 字符本身,请使用 \^。 |
$ | 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。 |
\b | 匹配一个单词边界,即字与空格间的位置。 |
\B | 非单词边界匹配。 |
()匹配符
(pattern) | 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。 |
(?:pattern) | 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。 |
(?=pattern) | 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?<=pattern) | 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。 |
(?<!pattern) | 反向否定预查,与正向否定预查类似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。 |
[]匹配符
[xyz] | 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'、'l'、'i'、'n'。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。 |
字符簇
连字号可以表示一个字符的范围
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\w | 匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。 |
\W | 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。 |
运算符优先级
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。
下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
运算符 | 描述 |
\ | 转义符 |
(), (?:), (?=), [] | 圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m} | 限定符 |
^, $, \任何元字符、任何字符 | 定位点和序列(即:位置和顺序) |
| | 替换,"或"操作 |
示例1:^匹配字符串开头
以下匹配以fan1开头的字符串,不包括换行符,即以fan1开头的行
import re
s = 'fan1 is ok\nfan2 is ok'
patt = re.compile('^fan1.*')
a = re.search(patt,s)
print(a.group())
fan1 is ok
示例2:. 搭配re.DOTALL或者(.|\n)
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
以下匹配fan1开头的字符串,包括换行符,即fan1到结尾
import re
s = 'fan1 is ok\nfan2 is ok'
patt = re.compile('^fan1.*',re.DOTALL)
a = re.search(patt,s)
print(a.group())
fan1 is ok
fan2 is ok
>>> s = 'fan1 is ok\nfan2 is ok'
>>> patt = re.compile('^fan1(.|\n)*')
>>> re.search(patt,s).group()
'fan1 is ok\nfan2 is ok'
示例3:贪婪模式匹配
* 和 + 限定符都是贪婪的,会尽可能多的匹配
>>> re.search('<.*>','<ab><cd>').group()
'<ab><cd>'
>>> re.search('<.+>','<ab><cd>').group()
'<ab><cd>'
示例4:非贪婪匹配或最小匹配
* 和 + 等限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。
>>> re.search('<.*?>','<ab><cd>').group()
'<ab>'
>>> re.search('<.+?>','<ab><cd>').group()
'<ab>'
示例5:. 匹配除换行符(\n、\r)之外的任何单个字符。
. 匹配除换行符(\n、\r)之外的任何单个字符。
要匹配包括 '\n' 在内的任何字符,请使用像"(.|\n)"的模式。
或者配置re.S(re.DOTALL)
>>> re.search('is.*ok','fan1 is ok\nfan2 is ok').group()
'is ok' #不能匹配\n
>>> re.search('is(.|\n)*ok','fan1 is ok\nfan2 is ok').group()
'is ok\nfan2 is ok' #可以匹配\n
>>> re.search('is(.|\n)*?ok','fan1 is ok\nfan2 is ok').group()
'is ok' #非贪婪模式
>>> re.search('is.*ok','fan1 is ok\nfan2 is ok',re.S).group()
'is ok\nfan2 is ok'
示例6:多行匹配
re.M:^$标志将会匹配每一行,默认^和$只会匹配第一行
按行,每行都做匹配,以\n为换行符匹配行
>>> re.findall('^fan(.*)ok','fan1 is ok\nfan2 is ok')
['1 is ']
>>> re.findall('^fan(.*)ok','fan1 is ok\nfan2 is ok',re.S)
['1 is ok\nfan2 is ']
>>> re.findall('^fan(.*)ok','fan1 is ok\nfan2 is ok',re.M)
['1 is ', '2 is ']