文章目录
re.match函数re.search方法re.match与re.search的区别正则表达式修饰符 - 可选标志检索和替换re.subrepl 参数是一个函数'(?P...)' 分组匹配正则表达式模式pile 函数findallre.finditerre.split参考re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
本章节主要介绍Python中常用的正则表达式处理函数。
re.match函数
re.match(pattern, string, flags=0) 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
匹配成功re.match方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
import reprint(re.match('www', '').span()) # 在起始位置匹配print(re.match('com', '')) # 不在起始位置匹配
(0, 3)None
正则表达式匹配字符的格式
line = "Cats are smarter than dogs"matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)if matchObj:print ("matchObj.grous() : ", matchObj.groups())print ("matchObj.group() : ", matchObj.group())print ("matchObj.group(1) : ", matchObj.group(1))print ("matchObj.group(2) : ", matchObj.group(2))else:print ("No match!!")"""首先,这是一个字符串,前面的一个 r 表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。但是这个字符串里没有反斜杠,所以这个 r 可有可无。(.*) 第一个匹配分组,.* 代表匹配除换行符之外的所有字符。(.*?) 第二个匹配分组,.*? 后面多个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符后面的一个 .* 没有括号包围,所以不是分组,匹配效果和第一个一样,但是不计入匹配结果中。"""
matchObj.grous() : ('Cats', 'smarter')matchObj.group() : Cats are smarter than dogsmatchObj.group(1) : CatsmatchObj.group(2) : smarter
# 大小写h都可以的情况ret = re.match( "[hH]" , "hello Python" )print(ret.group()) ret = re.match( "[hH]" , "Hello Python" )print(ret.group())ret = re.match( "[hH]ello Python" , "Hello Python" )print(ret.group())
hHHello Python
# 匹配0到9第一种写法ret = re.match( "[0123456789]l like tensorflow" , "6l like tensorflow" )print(ret.group())# 匹配0到9第二种写法ret = re.match( "[0-9]l like tensorflow" , "6l like tensorflow" )print(ret.group())
6l like tensorflow6l like tensorflow
# 使用\d进行匹配ret = re.match( "嫦娥\d号" , "嫦娥1号发射成功" )print(ret.group())
嫦娥1号
#匹配出,一个字符串第一个字母为大写字符,后面都是小写字母ret = re.match( "[A-Z][a-z]*" , "MnnM" )print(ret.group())ret = re.match( "[A-Z][a-z]*" , "Aabcdef" )print(ret.group())
MnnAabcdef
匹配出,变量名是否有效
备注:
(1) 变量名只能是 字母、数字或下划线的任意组合
(2)变量名的第一个字符不能是数字
(3) 关键字不能声明为变量名,例如as / lambda/ python/ else /class /global/ 等等
names = ["name1", "_name", "2_name", "__name__"]for name in names:ret = re.match("[a-zA-Z_]+[\w]*",name)#\w匹配单词字符if ret:print("变量名 %s 符合要求" % ret.group())else:print("变量名 %s 非法" % name)
变量名 name1 符合要求变量名 _name 符合要求变量名 2_name 非法变量名 __name__ 符合要求
re.search方法
re.search(pattern, string, flags=0)扫描整个字符串并返回第一个成功的匹配。
函数语法:
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
import reprint(re.search('www', '').span()) # 在起始位置匹配print(re.search('com', '').span()) # 不在起始位置匹配
(0, 3)<re.Match object; span=(11, 14), match='com'>
re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
正则表达式修饰符 - 可选标志
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:
import reline = "Cats are smarter than dogs";matchObj = re.match( r'dogs', line, re.M|re.I)if matchObj:print("match --> matchObj.group() : ", matchObj.group())else:print("No match!!")matchObj = re.search( r'dogs', line, re.M|re.I)if matchObj:print ("search --> searchObj.group() : ", matchObj.group())else:print( "No match!!")
No match!!search --> searchObj.group() : dogs
检索和替换re.sub
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。
语法:
re.sub(pattern, repl, string, count=0, flags=0)
参数:
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
import rephone = "-959-559 # 这是一个国外电话号码"# 删除字符串中的 Python注释 num = re.sub(r'#.*$', "", phone)print ("电话号码是: ", num)# 删除非数字(-)的字符串 num = re.sub(r'\D', "", phone)print ("电话号码是: ", num)
电话号码是: -959-559 电话号码是: 959559
repl 参数是一个函数
以下实例中将字符串中的匹配的数字乘以 2:
# 将匹配的数字乘以 2def double(matched):value = int(matched.group('value'))return str(value * 2)s = 'A23G4HFD567'print(re.sub('(?P<value>\d+)', double, s))print(re.search('(?P<value>\d+)',s).groupdict())print(re.search('(?P<value>\d+)',s))
A46G8HFD1134{'value': '23'}<re.Match object; span=(1, 3), match='23'>
‘(?P…)’ 分组匹配
import res = '1102231990xxxxxxxx'res = re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<born_year>\d{4})',s)print(res.groupdict())
{'province': '110', 'city': '223', 'born_year': '1990'}
正则表达式模式
模式字符串使用特殊的语法来表示一个正则表达式:
字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。
多数字母和数字前加一个反斜杠时会拥有不同的含义。
标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。
反斜杠本身需要使用反斜杠转义。
由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r’\t’,等价于 ‘\t’)匹配相应的特殊字符。
下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。
pile 函数
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
语法格式为:
pile(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 为了增加可读性,忽略空格和 # 后面的注释
pattern = pile(r'\d+')# 用于匹配至少一个数字m = pattern.match('one12twothree34four') # 查找头部,没有匹配print (m)m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配print (m)m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配print (m)m.group(0) # 可省略 0
NoneNone<re.Match object; span=(3, 5), match='12'>'12'
m.start(0) # 可省略 0
3
m.end(0)# 可省略 0
5
m.span(0) # 可省略 0
(3, 5)
在上面,当匹配成功时返回一个 Match 对象,其中:
group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
span([group]) 方法返回 (start(group), end(group))。
findall
findall(string[, pos[, endpos]]):在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
注意: match 和 search 是匹配一次 findall 匹配所有。
参数:
string : 待匹配的字符串。
pos : 可选参数,指定字符串的起始位置,默认为 0。
endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
pattern = pile(r'\d+') # 查找数字result1 = pattern.findall('runoob 123 google 456')result2 = pattern.findall('run88oob123google456', 0, 10)print(result1)print(result2)
['123', '456']['88', '12']
re.finditer
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.finditer(pattern, string, flags=0)
it = re.finditer(r"\d+","12a32bc43jf3") for match in it: print (match.group() )
1232433
re.split
split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
re.split(pattern, string[, maxsplit=0, flags=0])
参数:
参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
maxsplit 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
re.split('\W+', 'runoob, runoob, runoob"/.') #匹配1个或多个非字母数字及下划线
['runoob', 'runoob', 'runoob', '']
re.split('(\W+)', ' runoob, runoob, runoob.')
['', ' ', 'runoob', ', ', 'runoob', ', ', 'runoob', '.', '']
re.split('\W+', ' runoob, runoob, runoob.', 1)
['', 'runoob, runoob, runoob.']
参考
/python/python-reg-expressions.html#flags