re模块
一:什么是正则?
正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
生活中处处都是正则:
比如我们描述:4条腿
你可能会想到的是四条腿的动物或者桌子,椅子等
继续描述:4条腿,活的
就只剩下四条腿的动物这一类了
二:常用匹配模式(元字符)
1 # =================================匹配模式================================= 2 #一对一的匹配 3 # 'hello'.replace(old,new) 4 # 'hello'.find('pattern') 5 6 #正则匹配 7 import re 8 #\w与\W 9 print(re.findall('\w','hello egon 123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3'] 10 print(re.findall('\W','hello egon 123')) #[' ', ' '] 11 12 #\s与\S 13 print(re.findall('\s','hello egon 123')) #[' ', ' ', ' ', ' '] 14 print(re.findall('\S','hello egon 123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3'] 15 16 #\n \t都是空,都可以被\s匹配 17 print(re.findall('\s','hello \n egon \t 123')) #[' ', '\n', ' ', ' ', '\t', ' '] 18 19 #\n与\t 20 print(re.findall(r'\n','hello egon \n123')) #['\n'] 21 print(re.findall(r'\t','hello egon\t123')) #['\n'] 22 23 #\d与\D 24 print(re.findall('\d','hello egon 123')) #['1', '2', '3'] 25 print(re.findall('\D','hello egon 123')) #['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' '] 26 27 #\A与\Z 28 print(re.findall('\Ahe','hello egon 123')) #['he'],\A==>^ 29 print(re.findall('123\Z','hello egon 123')) #['he'],\Z==>$ 30 31 #^与$ 32 print(re.findall('^h','hello egon 123')) #['h'] 33 print(re.findall('3$','hello egon 123')) #['3'] 34 35 # 重复匹配:| . | * | ? | .* | .*? | + | {n,m} | 36 #. 37 print(re.findall('a.b','a1b')) #['a1b'] 38 print(re.findall('a.b','a1b a*b a b aaab')) #['a1b', 'a*b', 'a b', 'aab'] 39 print(re.findall('a.b','a\nb')) #[] 40 print(re.findall('a.b','a\nb',re.S)) #['a\nb'] 41 print(re.findall('a.b','a\nb',re.DOTALL)) #['a\nb']同上一条意思一样 42 43 #* 44 print(re.findall('ab*','bbbbbbb')) #[] 45 print(re.findall('ab*','a')) #['a'] 46 print(re.findall('ab*','abbbb')) #['abbbb'] 47 48 #? 49 print(re.findall('ab?','a')) #['a'] 50 print(re.findall('ab?','abbb')) #['ab'] 51 #匹配所有包含小数在内的数字 52 print(re.findall('\d+\.?\d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3'] 53 54 #.*默认为贪婪匹配 55 print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b'] 56 57 #.*?为非贪婪匹配:推荐使用 58 print(re.findall('a.*?b','a1b22222222b')) #['a1b'] 59 60 #+ 61 print(re.findall('ab+','a')) #[] 62 print(re.findall('ab+','abbb')) #['abbb'] 63 64 #{n,m} 65 print(re.findall('ab{2}','abbb')) #['abb'] 66 print(re.findall('ab{2,4}','abbb')) #['abb'] 67 print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+' 68 print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*' 69 70 #[] 71 print(re.findall('a[1*-]b','a1b a*b a-b')) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾 72 print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b'] 73 print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b'] 74 print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #[]内的^代表的意思是取反,所以结果为['a=b'] 75 print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) #[]内的^代表的意思是取反,所以结果为['a=b'] 76 77 #\# print(re.findall('a\\c','a\c')) #对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常 78 print(re.findall(r'a\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义 79 print(re.findall('a\\\\c','a\c')) #同上面的意思一样,和上面的结果一样都是['a\\c'] 80 81 #():分组 82 print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab'] 83 print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的ab 84 print(re.findall('(?:ab)+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容 85 print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击</a>'))#['http://www.baidu.com'] 86 print(re.findall('href="(?:.*?)"','<a href="http://www.baidu.com">点击</a>'))#['href="http://www.baidu.com"'] 87 88 #| 89 print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))
1 # str1 = '1abc a1 c aac aAc\n \taBc asd aaaaac a-c a/c a *c a+c abasd = a1c a2c' 2 import re 3 # print(re.findall('\w',str1)) #\w---匹配字母数字及下划线 4 # print(re.findall('\W',str1)) #\w---匹配非字母数字及下划线 \n \t 5 # print(re.findall('\s',str1)) #匹配任意空白字符\n\t\r\f 6 # print(re.findall('\S',str1)) #匹配非空白字符 7 # print(re.findall('\d',str1)) #匹配数字等价0-9 8 # print(re.findall('\D',str1)) #匹配任意非数字0-9 9 # print(re.findall('\Aac',str1)) #匹配字母开始 10 # print(re.findall('\\n\Z',str1)) #匹配字母结束,只匹配到换行前的结束字符串 11 # print(re.findall('\G',str1)) #匹配字母结束,只匹配到换行前的结束字符串 12 # print(re.findall('\n',str1)) #匹配换行符 13 # print(re.findall('\t',str1)) #匹配换行符 14 # print(re.findall('^1abc',str1)) #匹配以什么开头 15 # print(re.findall('c$',str1)) #匹配以什么结尾 16 str1 = '1abbb a1 a\nbc aac aAc\n \taBc asd aaaaac a-c a/c a *c a+c abasd = a1c a2c' 17 # print(re.findall('a.b',str1))#匹配中间是任意字符除了换行符 18 # print(re.findall('a.b',str1,re.S))#匹配中间是任意字符包含换行符 19 # print(re.findall('a.b',str1,re.DOTALL))#匹配中间是任意字符包含换行符 20 # print(re.findall('ab*',str1)) #匹配0个或多个表达式 21 # print(re.findall('ab+',str1)) #匹配1个或多个表达式 22 # print(re.findall('ab?',str1)) #匹配0个或1个表达式 23 # print(re.findall('ab?a',str1)) #匹配0个或1个表达式指代找b 24 # print(re.findall('ab{2}','abbb aabxbaa')) #表示1个a2个b 25 # print(re.findall('a[1*-]b','a1b a\nb a*b a-b')) #['a1b', 'a*b', 'a-b'] 26 # print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^表示取反 27 # print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #['a1b'] 28 # print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #['aeb'] 29 # print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb'))#['aeb', 'aEb'] 30 # print(re.findall(r'a\\c','a\c')) 31 # print(re.findall('(ab)+123','ababab123')) 32 # print(re.findall('(?:ab)+123','xxxaab123')) #['ab123'] 33 # print(re.findall('(?:ab)+123','12abab123'))#['abab123']如果有相同的ab连接在一起就一起显示 34 # print(re.findall('compan(?:ies|y)','Too many companies have gone bankrupt, and the next one is my company')) 35 # print(re.findall('href="(.*?)"','<p>段落</p><a href="https://www.sb.com">点我啊</a><h1>标题</h1><a href="https://www.sb.com">点我啊</a>')) 36 # print(re.findall('a|b','ab123abasdfaf')) 37 # print(re.split('ab','abcd')) #['', 'cd'] 38 # print(re.split('[ab]','abcd')) #['', '', 'cd'] #如果是列表按照索引取 39 # print('===>',re.sub('a','A','alex make love')) #===> Alex mAke love,不指定n,默认替换所有 40 # print('===>',re.sub('a','A','alex make love',1)) #===> Alex make love 41 42 # obj=re.compile('\d{3}') #查找3个数字还要连续的 43 # # print(obj.search('abc123eee1e').group()) #12 44 # print(obj.findall('abc123eeee')) #['12'],重用了obj 45 46 47 # print(re.findall('a,b|c','ac,a,b,accc')) 48 # print(re.findall('ab?','a'))
1 import re 2 #1 3 print(re.findall('e','alex make love') ) #['e', 'e', 'e'],返回所有满足匹配条件的结果,放在列表里 4 #2 5 print(re.search('e','alex make love').group()) #e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 6 7 #3 8 print(re.match('e','alex make love')) #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match 9 10 #4 11 print(re.split('[ab]','abcd')) #['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割 12 13 #5 14 print('===>',re.sub('a','A','alex make love')) #===> Alex mAke love,不指定n,默认替换所有 15 print('===>',re.sub('a','A','alex make love',1)) #===> Alex make love 16 print('===>',re.sub('a','A','alex make love',2)) #===> Alex mAke love 17 print('===>',re.sub('^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$',r'\5\2\3\4\1','alex make love')) #===> love make alex 18 19 print('===>',re.subn('a','A','alex make love')) #===> ('Alex mAke love', 2),结果带有总共替换的个数 20 21 22 #6 23 obj=re.compile('\d{2}') 24 25 print(obj.search('abc123eeee').group()) #12 26 print(obj.findall('abc123eeee')) #['12'],重用了obj
1 import re 2 print(re.findall("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")) #['h1'] 3 print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>").group()) #<h1>hello</h1> 4 print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>").groupdict()) #<h1>hello</h1> 5 6 print(re.search(r"<(\w+)>\w+</(\w+)>","<h1>hello</h1>").group()) 7 print(re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>").group())
1 #计算器作业参考:http://www.cnblogs.com/wupeiqi/articles/4949995.html 2 expression='1-2*((60+2*(-3-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))' 3 4 content=re.search('\(([\-\+\*\/]*\d+\.?\d*)+\)',expression).group() #(-3-40.0/5)
1 #为何同样的表达式search与findall却有不同结果: 2 print(re.search('\(([\+\-\*\/]*\d+\.?\d*)+\)',"1-12*(60+(-40.35/5)-(-4*3))").group()) #(-40.35/5) 3 print(re.findall('\(([\+\-\*\/]*\d+\.?\d*)+\)',"1-12*(60+(-40.35/5)-(-4*3))")) #['/5', '*3'] 4 5 #看这个例子:(\d)+相当于(\d)(\d)(\d)(\d)...,是一系列分组 6 print(re.search('(\d)+','123').group()) #group的作用是将所有组拼接到一起显示出来 7 print(re.findall('(\d)+','123')) #findall结果是组内的结果,且是最后一个组的结果
1 #_*_coding:utf-8_*_ 2 __author__ = 'Linhaifeng' 3 #在线调试工具:tool.oschina.net/regex/# 4 import re 5 6 s=''' 7 http://www.baidu.com 8 [email protected] 9 你好 10 010-3141 11 ''' 12 13 #最常规匹配 14 # content='Hello 123 456 World_This is a Regex Demo' 15 # res=re.match('Hello\s\d\d\d\s\d{3}\s\w{10}.*Demo',content) 16 # print(res) 17 # print(res.group()) 18 # print(res.span()) 19 20 #泛匹配 21 # content='Hello 123 456 World_This is a Regex Demo' 22 # res=re.match('^Hello.*Demo',content) 23 # print(res.group()) 24 25 26 #匹配目标,获得指定数据 27 28 # content='Hello 123 456 World_This is a Regex Demo' 29 # res=re.match('^Hello\s(\d+)\s(\d+)\s.*Demo',content) 30 # print(res.group()) #取所有匹配的内容 31 # print(res.group(1)) #取匹配的第一个括号内的内容 32 # print(res.group(2)) #去陪陪的第二个括号内的内容 33 34 35 36 #贪婪匹配:.*代表匹配尽可能多的字符 37 # import re 38 # content='Hello 123 456 World_This is a Regex Demo' 39 # 40 # res=re.match('^He.*(\d+).*Demo$',content) 41 # print(res.group(1)) #只打印6,因为.*会尽可能多的匹配,然后后面跟至少一个数字 42 43 44 #非贪婪匹配:?匹配尽可能少的字符 45 # import re 46 # content='Hello 123 456 World_This is a Regex Demo' 47 # 48 # res=re.match('^He.*?(\d+).*Demo$',content) 49 # print(res.group(1)) #只打印6,因为.*会尽可能多的匹配,然后后面跟至少一个数字 50 51 52 #匹配模式:.不能匹配换行符 53 content='''Hello 123456 World_This 54 is a Regex Demo 55 ''' 56 # res=re.match('He.*?(\d+).*?Demo$',content) 57 # print(res) #输出None 58 59 # res=re.match('He.*?(\d+).*?Demo$',content,re.S) #re.S让.可以匹配换行符 60 # print(res) 61 # print(res.group(1)) 62 63 64 #转义:\ 65 66 # content='price is $5.00' 67 # res=re.match('price is $5.00',content) 68 # print(res) 69 # 70 # res=re.match('price is \$5\.00',content) 71 # print(res) 72 73 74 #总结:尽量精简,详细的如下 75 # 尽量使用泛匹配模式.* 76 # 尽量使用非贪婪模式:.*? 77 # 使用括号得到匹配目标:用group(n)去取得结果 78 # 有换行符就用re.S:修改模式