import re# . ^ $ * + ? { } [ ] | ( ) \ 元字符# " . " 通配符re.findall(‘a..x‘,‘assxfsdf‘) #一个匹配 [‘assx‘]re.findall(‘a..x‘,‘assxbasdxds‘) #多个匹配 [‘assx‘,‘asdx‘]re.findall(‘a..x‘,‘asaxfxdf‘) #交差匹配 [‘asax‘]re.findall(‘a..x‘,‘asaasdasd‘) #无 []# " ^ " 以....字符串开头," ^ "不能放在re开头re.findall(‘^a..x‘,‘assxfsdf‘) #一个匹配 [‘assx‘]re.findall(‘^a..x‘,‘assxbasdxds‘) #多个匹配 [‘assx‘]re.findall(‘^a..x‘,‘bassxbasdxds‘) #无 []re.findall(‘^a..x‘,‘asaasdasd‘) #无 []#" $ " 以....字符串结尾re.findall(‘a..x$‘,‘assxfsdf‘) # []re.findall(‘a..x$‘,‘assxbasdadsx‘) # [‘adsx‘]re.findall(‘a..x$‘,‘assxbasdadsx$‘) # []# " * " 代表0-无穷次其前面的字符个数re.findall(‘d*‘,‘dasdddasd‘) # [‘d‘,‘‘,‘ddd‘,‘d‘,‘‘] 为啥最后多了一位re.findall(‘alex*‘,‘dalesdalexxsdale‘) # [‘ale‘,‘alexx‘,‘ale‘]# " + " 代表1-无穷次其前面的字符个数re.findall(‘d+‘,‘d‘] 贪婪匹配:按最多次的匹配来返回re.findall(‘alex+‘,‘dalesdalexxsd‘) # [‘alexx‘]# " ? " 代表0或1次其前面的字符个数re.findall(‘d?‘,‘‘] 最后还是多了一位re.findall(‘alex?‘,‘alex‘,‘ale‘]# " {} " {0,}==* {1,}==+ {0,1}==? 可认为控制重复的次数re.findall(‘d{1}‘,‘d‘]re.findall(‘d{0}‘,‘dasdddasd‘) # [‘‘,‘‘] 还是多了一位re.findall(‘d{0,3}‘,‘‘] 还是多了一位re.findall(‘d{1,‘d‘]re.findall(‘alex?‘,‘ale‘]# 加一个? " ? " 把贪婪匹配转换为惰性匹配,按最小次匹配re.findall(‘d+?‘,‘d‘]re.findall(‘d*?‘,‘daddsd‘) # [‘‘,‘‘] 没搞懂这个re.findall(‘alex*?‘,‘ale‘,‘ale‘]re.findall(‘alex+?‘,‘dalesdalexxsdale‘) # [‘alex‘]# " [] " 字符集 或的意思re.findall("x[yz]","xyzxz") # [‘xy‘,‘xz‘]re.findall("x[yz]p","xypzxzpxz") # [‘xyp‘,‘xzp‘]re.findall("x[yz]p?",‘xzp‘,‘xz‘]re.findall("x[y,z]p?","xypzxzpx,z") # [‘xyp‘,‘x,‘],逗号只是普通字符re.findall(‘x[y*z]‘,‘xyx*xzjkx‘) # [‘xy‘,‘x*‘,‘xz‘] 字符集[]中间的都是普通字符re.findall(‘x[a-z]‘,‘xz‘] - 横杠代表的是范围,特殊字符re.findall(‘x[a-z*]‘,‘xz‘]re.findall(‘x[a-z]*‘,‘xyx*xzjkx‘) # [‘xyx‘,‘xzjkx‘]re.findall(‘x[^a-z]*‘,‘xZx*x9jkx!xAWExa7,xz9x99x‘)# [‘xZ‘,‘x9‘,‘x!‘,‘xAWE‘,‘x‘,‘x99‘,‘x‘] " ^ " 尖角代表的是非,非a-z,特殊字符re.findall(‘x[^a-z]‘,‘xZx*x9jkx!xAWE9x99x‘) # [‘xZ‘,‘xA‘,‘x9‘]#小练习,如何取出12+(34*6+2-5*(2-1))里面的(2-1)?re.findall(‘\([^()]*\)‘,‘12+(34*6+2-5*(2-1))‘) # [‘(2-1)‘] , \反斜杠,转义字符。也是字符集里面的第3个特殊字符# " \ " 反斜杠转义字符,可以让有意义变成没意义,没意义变成有意义# 反斜杠后边跟元字符去除特殊功能,比如\.# 反斜杠后边跟普通字符实现特殊功能,比如\d# \d 匹配任何十进制数;它相当于类 [0-9]。# \D 匹配任何非数字字符;它相当于类 [^0-9]。# \s 匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。# \S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。# \w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。# \W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]# \b 匹配一个特殊字符边界,比如空格 ,&,#等re.findall(‘\d‘,‘12+(34*6+2-5*(2-1))‘) # [‘1‘,‘2‘,‘3‘,‘4‘,‘6‘,‘5‘,‘1‘]re.findall(‘\d+‘,‘12+(34*6+2-5*(2-1))‘) # [‘12‘,‘34‘,‘1‘]re.findall(‘[0-9]+‘,‘1‘]re.findall(‘\D‘,‘12+(34*6+2-5*(2-1))‘) # [‘+‘,‘(‘,‘*‘,‘+‘,‘-‘,‘)‘,‘)‘]re.findall(‘\D+‘,‘12+(34*6+2-5*(2-1))‘) # [‘+(‘,‘*(‘,‘))‘]re.findall(‘[^0-9]+‘,‘))‘]re.findall(‘\s‘,‘hello world‘) # [‘ ‘]re.findall(‘\S+‘,‘hello world‘) #[‘hello‘,‘world‘]re.findall(‘\w+‘,‘hello world 333 _‘) # [‘hello‘,‘world‘,‘333‘,‘_‘]re.findall(‘\W+‘,‘hello world 333 _‘) # [‘ ‘,‘ ‘,‘ ‘]re.findall(‘www.baidu‘,‘www.baidu‘) # [‘www.baidu‘]re.findall(‘www.baidu‘,‘www(baidu‘) # [‘www(baidu‘]re.findall(‘www\.baidu‘,‘www.baidu‘) # [‘www.baidu‘]re.findall(‘www\.baidu‘,‘www(baidu‘) # []re.findall(‘www*baidu‘,‘www*baidu‘) # []re.findall(‘www\*baidu‘,‘www*baidu‘) # [‘www*baidu‘]re.findall(‘I‘,‘hello I am LIST‘) # [‘I‘,‘I‘]re.findall(‘^I‘,‘hello I am LIST‘) # []re.findall(‘I\b‘,‘hello I am LIST‘) # [] 为什么没成功?因为在python中\b就已经被赋予特殊含义了,所以在执行的时候,\b被python优先赋予了特殊意义re.findall(r‘I\b‘,‘hello I am LIST‘) # [‘I‘] r:raw string 原生字符串,加了r之后,\b就不是python的特殊含义了,而是re语言中的特殊含义re.findall(‘I\\b‘,‘hello I am LIST‘) # [‘I‘] 在python中,"\"也是转义字符,但python会把"\\"翻译成一个没有任何特殊意义的\字符,所以\b也就能被re语言使用了re.findall(‘c\\f‘,‘abc\ferwt‘) # [‘c\x0c‘] 传给re语言的是\f,显然在re语言中,\f并没有特殊的含义,所以能够匹配成功,但是对于\f这个返回值,python对它再进行了一次加工re.findall(‘c\l‘,‘abc\lerwt‘) # 为什么我报错,老师的能运行?re.findall(‘c\\l‘,‘abc\lerwt‘) # 为什么我报错,老师的能运行?re.findall(‘c\\\l‘,‘abc\lerwt‘) # [‘c\\l‘] 三个\\\也可以,但是这个知识点太细了,暂时跳过re.findall(‘c\\\\l‘,‘abc\lerwt‘) # [‘c\\l‘] 在python层面,4个\\\\就被翻译成无意义的两个\\字符,再传递给re语言就变成一个无意义的\re.findall(r‘c\\l‘,‘abc\lerwt‘) # [‘c\\l‘] 和上面这个一样的理解 # 至于为什么传回来的是两个\\,因为python解释器对其进行了处理 # 所以,可以简单记忆,当re要使用一个\的时候,你需要通过python给它传过去2个\\ # 当re需要使用2个\\的时候(去匹配\字符的时候),你就要通过python给它传过去4个\\\\# 问题来了!re.findall(‘www.baidu‘,‘www,baidu‘) # [‘www,baidu‘] 这个简单,可以理解,看下面re.findall(‘www\.baidu‘,baidu‘) # [] 为什么返回空?python层面,转义字符是不会传给re的,所以re收到的还是www.baidu,按理说,就可以匹配上www,baidu # 自己的强行解释,当re需要使用类似于\w,\d这种的时候,或者要实际去匹配\这个字符的时候,可以按照两层传递的逻辑去思考 # 当不是这两种情况的时候,就不要考虑两层了!!!!# " | " 管道符,代表或re.findall(r‘aa|b‘,‘abaaab‘) # [‘b‘,‘aa‘,‘b‘]# " () " 分组符re.findall(‘abc‘,‘abcabcabcabc‘) # [‘abc‘,‘abc‘,‘abc‘]re.findall(‘(abc)‘,‘abc‘]re.findall(‘(abc)*‘,‘‘]re.findall(‘(abc)+‘,‘abcabcabcabc‘) # [‘abc‘] 这是因为优先级的问题,在使用()的时候,匹配上之后,python会只返回()里面的内容re.findall(‘(?:abc)*‘,‘abcabcabcabc‘) # [‘abcabcabcabc‘,‘‘] 使用?:组合来去掉re模块()的这种优先级设置re.findall(‘(?:abc)+‘,‘abcabcabcabc‘) # [‘abcabcabcabc‘] 使用?:组合来去掉re模块()的这种优先级设置re.findall(‘(abc)?‘,‘abccc‘) # [‘abc‘]re.findall(‘abc+‘,‘abccc‘) # [‘abccc‘]re.findall(‘www\.(baidu|163)\.com‘,‘www.baidu.com‘) # [‘baidu‘] 分组符()的优先级太高,所以在能够匹配的情况下,只返回这个,这个和上面那个(abc)+的理解是一样的re.findall(‘www\.(baidu|163)\.com‘,‘www.163.com‘) # [‘163‘]re.findall(‘www\.(baidu|163)\.com‘,‘123dsdqwww.163.comwe12r‘) # [‘163‘]re.findall(‘www\.(baidu|163)\.com‘,‘weeerww.163.cwweomwe12r‘) # [] 不能匹配,就返回空re.findall(‘www\.(?:baidu|163)\.com‘,‘123dsdqwww.163.comwe12r‘) # [‘www.163.com‘] ?:可以去优先级re.findall(‘a(bc)|(nm)y‘,‘nmy‘) # [(‘‘,‘nm‘)] #分组符与其它符号一起用的时候,会涉及到优先级的问题。。。不太会re.findall(‘a(bc)|(nm)y‘,‘abcy‘) # [(‘bc‘,‘‘)]re.findall(‘a(bc)|(nm)y‘,‘abcnmy‘) # [(‘bc‘,‘‘),(‘‘,‘nm‘)]# 第2种方法 searchre.search(‘\d+‘,‘jiang2132zong34‘) # <re.Match object; span=(5,9),match=‘2132‘> search只会匹配第一个,而且返回一个对象re.search(‘\d{5}‘,‘jiang2132zong34‘) # 如果匹配不成功,则返回None,而不会返回一个空列表re.search(‘\d+‘,‘jiang2132zong34‘).group() # ‘2132‘,用对象下面的group方法来调用其中的匹配值re.search(‘(?P<name>[a-z]+)‘,‘jiang25zong33you18‘).group() # ‘jiang‘ 固定用法,给匹配的值加上name的标签re.search(‘(?P<name>[a-z]+)(?P<age>\d+)‘,‘jiang25zong33you18‘).group() # ‘jiang25‘re.search(‘(?P<name>[a-z]+)(?P<age>\d+)‘,‘jiang25zong33you18‘).group(‘name‘) # ‘jiang‘re.search(‘(?P<name>[a-z]+)(?P<age>\d+)‘,‘jiang25zong33you18‘).group(‘age‘) # ‘25‘# 第3种方法 match 只会从开头匹配.所以不常用,search完全可以取代matchre.match(‘\d+‘,‘12asd12ad‘) # <re.Match object; span=(0,2),match=‘12‘>re.match(‘\d+‘,‘12asd12ad‘).group() # ‘12‘# 第4种方法 split, 分割并返回元祖re.split(‘ ‘,‘hello world !‘) # [‘hello‘,‘!‘]re.split(‘[ |]‘,‘hello world|!‘) # [‘hello‘,‘!‘]re.split(‘[ab]‘,‘abc‘) # [‘‘,‘c‘] 返回的列表中并不会包含用于分割的元素re.split(‘a|b‘,‘abc‘) # [‘‘,‘c‘] 返回的列表中并不会包含用于分割的元素re.split(‘(ab)‘,‘ab‘,‘c‘] 例外的是,如果使用字符集()用于分割,那么这个元素就会被返回re.split(‘[ab]‘,‘asdabcd‘) # [‘‘,‘sd‘,‘cd‘]re.split(‘(ab)‘,‘asdabcd‘) # [‘asd‘,‘asdabcdabcccabccc‘,maxsplit=2) # [‘asd‘,‘cd‘,‘cccabccc‘]re.split(‘(ab)‘,2) # [‘asd‘,‘cccabccc‘]# 第5种方法 sub, 替换并返回字符串re.sub(‘\d‘,‘_‘,‘asd23j23jl32j4kj32k4jlk32j546kl‘) # ‘asd__j__jl__j_kj__k_jlk__j___kl‘re.sub(‘\d+‘,‘asd23j23jl32j4kj32k4jlk32j546kl‘) # ‘asd_j_jl_j_kj_k_jlk_j_kl‘re.sub(‘\d+‘,‘asd23j23jl32j4kj32k4jlk32j546kl‘,3) # ‘asd_j_jl_j4kj32k4jlk32j546kl‘# 第6种方法 subn, 替换并返回元祖(返回的字符串+匹配的次数)re.subn(‘\d‘,‘asd23j23jl32j4kj32k4jlk32j546kl‘) # (‘asd__j__jl__j_kj__k_jlk__j___kl‘,15)# 第7种方法 finditer,非常重要, 和findall的不同就是,将匹配的数据存到一个迭代器里面,在处理大数据的时候,非常节约内存re.findall(‘\d+‘,‘12k3e4k5j‘) # [‘12‘,‘5‘]re.finditer(‘\d+‘,‘12k3e4k5j‘) # <callable_iterator object at 0x0000022137C3D160>re_iter = re.finditer(‘\d+‘,‘12k3e4k5j‘)next(re_iter) # <re.Match object; span=(0,match=‘12‘>next(re_iter).group() # ‘3‘next(re_iter).group() # ‘4‘next(re_iter).group() # ‘5‘next(re_iter).group() # StopIteration# 特殊的一种方法,编译,compilecom=re.compile(‘\d+‘)com.findall(‘asd123jkl35‘) # [‘123‘,‘35‘]学习笔记为自己根据网络视频整理,侵必删