import re """ 使用match方法进行匹配 result = re.match(正则表达式,要匹配的字符串) 如果match匹配到数据的话,就可以使用group方法提取数据 注: 若字符串匹配正则表达式,则match方法返回匹配对象(Match Object), 否则返回None(不是空字符串) match方法是从左到右匹配(因为match的这种特性,所以 ^ 从字符串头开始匹配 可以不用写),匹配到不一样的地方,match方法就结束! """
""" . :匹配任意一个字符,\n除外 [] :匹配[]中列举的字符 \d : 数字,即0~9 \D : 非数字 \s : 空白字符,包括空格, \n , \t ,\r, 回车换行 \S :非空白字符 \w :单词,(可以看成是校验python变量名,实际两者没有任何关系,a~z , A~Z, 0~9 , _ ) \W : 非单词字符 """
In [1]: import re In [2]: re.match(\'admin\',\'good.admin\') In [3]: re.match(\'.+\',\'good.admin\') Out[3]: <re.Match object; span=(0, 10), match=\'good.admin\'> In [4]: re.match(\'.\',\'good.admin\') Out[4]: <re.Match object; span=(0, 1), match=\'g\'> In [5]: re.match(\'..\',\'good.admin\') Out[5]: <re.Match object; span=(0, 2), match=\'go\'> In [6]: re.match(\'.*\',\'good.admin\') Out[6]: <re.Match object; span=(0, 10), match=\'good.admin\'>
In [7]: re.match(\'\w\',\'good\') Out[7]: <re.Match object; span=(0, 1), match=\'g\'> In [8]: re.match(\'\w\',\'g1\') Out[8]: <re.Match object; span=(0, 1), match=\'g\'> In [9]: re.match(\'\W\',\'g1\')
# \w与g匹配,但是\W与1不相匹配,所以最终还是不匹配,返回None In [10]: re.match(\'\w\W\',\'g1\')
""" 边界问题 ^ : 匹配字符串开头 $ : 匹配结尾 \b : 匹配单词边界 \B : 匹配非单词边界 """
""" 匹配数量: * : 匹配一个字符出现0次或者无限多次 + :匹配一个字符出现1次或者无限多次 ? :匹配一个字符出现0次或者1次 {m} : 匹配一个字符出现m次 {m,}: 匹配一个字符至少出现m次 {m,n} : 匹配一个字符出现m到n次 """
""" 边界问题 ^ : 匹配字符串开头 $ : 匹配结尾 \b : 匹配单词边界 \B : 匹配非单词边界 """
\'\'\' 示例2:匹配手机号 \'\'\' r = re.match(\'1[35689]\d{9}$\',\'13218545678\') print(r) # <re.Match object; span=(0, 11), match=\'13218545678\'> r = re.match(\'1[35689]\d{9}$\',\'132185456789\') print(r) #None r = re.match(\'1[35689]\d{9}\',\'132185456789\') # 没有$符,无边界问题 print(r) #<re.Match object; span=(0, 11), match=\'13218545678\'> r = re.match(\'1[35689]\d{9}\',\'13218545aaaa6789\') print(r) #None
\'\'\' 示例3: 匹配单词边界 \'\'\' # r:去掉转义; ^:字符串开头, od\b:od是单词边界 r = re.match(r\'^\w+od\b\',\'good\') print(r) # <re.Match object; span=(0, 4), match=\'good\'> r = re.match(r\'^\w+od\b\',\'gooder\') print(r) #None r = re.match(r\'^\w+\bod\b\',\'good\') print(r) #None r = re.match(r\'^\w+\bod\b\',\'jd od\') print(r) #None, 因为\b只表示单词边界,并不表示空格 r = re.match(r\'^\w+\s\bod\b\',\'jd od\') # 这里用\s去匹配了jd与od之间的空白字符 print(r) #<re.Match object; span=(0, 5), match=\'jd od\'> r = re.match(r\'^\w+od\B\',\'gooder\') print(r) #<re.Match object; span=(0, 4), match=\'good\'> r = re.match(r\'^\w+od\B\',\'good\') print(r) #None
""" 分组: | : 表示左右任意一个表达式 (ab) : 将括号中的字符作为一个分组 \num : 引用分组num匹配到的字符串 (?P<name>) : 分组起别名 (?P=name) : 引用别名为name分组匹配到的字符串 """
\'\'\'示例4 匹配0-100之间的数字\'\'\' r = re.match(r\'[1-9]\d?$|0$|100$\',\'100\' ) print(r) #<re.Match object; span=(0, 3), match=\'100\'> # 改进版 r = re.match(r\'[1-9]?\d?$|100$\',\'0\' ) print(r) #<re.Match object; span=(0, 1), match=\'0\'>
\'\'\' 示例5: 从字符串中抽取特定的字符 , 如抽取h1标签之间的字符 \'\'\' s = \'<h1>我是中国人</h1>\' r = re.match(r"<h1>(.*)</h1>",s) print(r.group()) #<h1>我是中国人</h1> print(r.group(1)) # 我是中国人 , 1 : 表过正则表达式分组第1次出现 s = \'<h1>打倒小日本</h1>\' r = re.match(r"<h1>(.*)</h1>",s) print(r.group()) #<h1>打倒小日本</h1> print(r.group(1)) # 打倒小日本 , 1 : 表过正则表达式分组第1次出现 s = \'<h1>打倒小日本 我是中国人</h1>\' r = re.match(r"<h1>(\D*)\s(\D*)</h1>",s) print(r.group()) #<h1>打倒小日本 我是中国人</h1> print(r.group(1)) # 打倒小日本 取第1个分组的值 print(r.group(2)) # 我是中国人 取第2个分组的值 print(r.groups()) # 将所有的分组结果以一个元组的形式打印出来
\'\'\' 示例6: 匹配<html><h1>zhengqinfeng</h1></html>,且,首尾尖括号中的内容相同、内层尖括号中的内容相同 \'\'\' s = \'<html><h1>zhengqinfeng</h1></html>\' r = re.match(r\'<.+><.+>.+</.+></.+>\',s) print(r) #<re.Match object; span=(0, 34), match=\'<html><h1>zhengqinfeng</h1></html>\'> # 上面的正则貌似完成了需要,实则不然, 它并不满足"且"后面的要求,所以正确的正则如下 r= re.match(r\'<(.+)><(.+)>.+</\2></\1>\',s) # 正则前面加r,不会进行字符串转义 print(r) #<re.Match object; span=(0, 34), match=\'<html><h1>zhengqinfeng</h1></html>\'> s = \'<html><h1>zhengqinfeng</h2></html>\' r= re.match(r\'<(.+)><(.+)>.+</\2></\1>\',s) # 正则前面加r,不会进行字符串转义 print(r) #None """ 使用()时,re会记录()中的内容,我们可以使用\num来引用 在上面的示例中, 第一次出现的(.+) re会记录为num =1 ; 第二次出现的 (.+) re会记录为num =2 在后面使用时,可以直接\1, \2来引用值 """
由例5,例6两示例可知,正则分组用途如下:
1. 从字符串提取出特定的字符
2. 动态引用分组内容进行匹配
\'\'\' 示例7: 抽取邮箱账号 (163|126|135|qq|gmail) :表示匹配其中一种 \. : 匹配邮箱中的. (com|cn|net) : 表示匹配邮箱后缀中的一种 $ : 表结束 ,也就是说邮箱是以com,cn,或者是net结尾 \'\'\' p = r\'(\w+)@(163|126|135|qq|gmail)\.(com|cn|net)$\' r = re.match(p, \'132@163.com\') print(r) print(r.groups()) print(r.group(1)) # 提取邮箱账号 132
\'\'\' 示例8: 正则分组取名字 \'\'\' s = \'<html><h1>zhengqinfeng</h1></html>\' r = re.match(\'<(?P<key1>.+)><(?P<key2>.+)>.+</(?P=key2)></(?P=key1)>\',s) print(r) # <re.Match object; span=(0, 34), match=\'<html><h1>zhengqinfeng</h1></html>\'> print(r.groups()) # (\'html\', \'h1\')