正则就是用一些具有特殊含义的符号组合在一起(成为正则表达式)来描述字符或字符串的方法.或者说:正则就是用来描述一类事物的规则.它嵌套在Python中,并通过re模块实现,正则表达式模式被编译成一系列的字节码,然后用C编写的匹配引擎执行.
元字符
\w 匹配字母(包含中文)或数字或下划线
\W 非 \w的
import re s = re.findall('\w','123euiooj--=,..') print(s) 运行结果: ['1', '2', '3', 'e', 'u', 'i', 'o', 'o', 'j'] s = re.findall('\W','123euiooj--=,..') print(s) 运行结果: ['-', '-', '=', ',', '.', '.']
\s匹配任意的空白符
\S 匹配 非\s
s = re.findall('\s','nihao, my world ') print(s) 运行结果: [' ', ' ', ' '] s = re.findall('\S','nihao, my world ') print(s) 运行结果: ['n', 'i', 'h', 'a', 'o', ',', 'm', 'y', 'w', 'o', 'r', 'l', 'd']
\d匹配数字
\D匹配非\d
s = re.findall('\d','nihao123456') print(s) 运行结果: ['1', '2', '3', '4', '5', '6'] s = re.findall('\D','nihao123456') print(s) 运行结果: ['n', 'i', 'h', 'a', 'o']
\A从字符串开头匹配
s = re.findall('\An','nnnihao123456') print(s) 运行结果: ['n']
\Z匹配字符串的结束,如果是换行,只匹配到换行前的结果
s = re.findall('n\Z','ihao123456n') print(s) 打印结果: ['n']
\n匹配一个换行符
s = re.findall('\n','ihao123456n\n') print(s) 打印结果: ['\n']
\t匹配一个制表符
s = re.findall('\n\t','ihao123456n\n\t') print(s) 打印结果: ['\n\t']
^匹配字符串的开始
s = re.findall('^a','aaaihao123456n') print(s)--跟\A功能类似 打印结果:['a']
$匹配字符串的结尾
s = re.findall('a$','ihao123456naaaa') print(s)--跟\Z功能类似 打印结果: ['a']
. 匹配任意字符,除了换行符,当re.dotall标记被指定时,则可以匹配包括换行符的任意字符
s = re.findall('.','ihao123456naa\n') print(s) 打印结果: ['i', 'h', 'a', 'o', '1', '2', '3', '4', '5', '6', 'n', 'a', 'a']
.可以匹配任意字符,那就说明必须至少有1个字符
print(re.findall('a.b', 'ab aab a*b a2b a牛b a\nb')) 打印结果: ['aab', 'a*b', 'a2b', 'a牛b']
当re.DOTALL被指定时,可以匹配换行符
print(re.findall('a.b','ab aab a*b a2b a牛b a\nb',re.DOTALL)) 打印结果: ['aab', 'a*b', 'a2b', 'a牛b', 'a\nb']
[...]匹配字符组中的字符
print(re.findall('a[abc]b', 'aab abb acb adb afb a_b')) 打印结果: ['aab', 'abb', 'acb']
[0-9]代表数字0到9的数字,[a-z]代表小写字母,[A-Z]代表大写字母
print(re.findall('a[0-9]b', 'a1b a3b aeb a*b arb a_b')) 打印结果: ['a1b', 'a3b']
- 在[]中表示范围,如果想要匹配上- 那么这个-符号不能放在中间
print(re.findall('a[-*+]b', 'a-b a*b a+b a/b a6b')) 打印结果: ['a-b', 'a*b', 'a+b']
[^...]匹配除了字符组中的字符的所有字符
print(re.findall('a[^a-z]b', 'acb adb a3b a*b')) 打印结果: ['a3b', 'a*b']
*匹配0个或多个左边的字符
print(re.findall('a*b', 'ab aab aaab abbb')) 打印结果: ['ab', 'aab', 'aaab', 'ab', 'b', 'b']
print(re.findall('ab*', 'ab aab aaab abbbbb')) 打印结果: ['ab', 'a', 'ab', 'a', 'a', 'ab', 'abbbbb']
+匹配一个或多个左边的字符
print(re.findall('a+b', 'ab aab aaab abbb')) 打印结果: ['ab', 'aab', 'aaab', 'ab']
?匹配0个或者1个左边的字符,非贪婪方式
print(re.findall('a?b', 'ab aab abb aaaab a牛b aba**b')) 打印结果: ['ab', 'ab', 'ab', 'b', 'ab', 'b', 'ab', 'b']
{n}精准匹配n个前面的表达式
print(re.findall('a{2}b', 'ab aab aaab aaaaabb')) 打印结果: ['aab', 'aab', 'aab']
{n,m}匹配n到m次由前面的正则表达式定义的片段,贪婪方式
print(re.findall('a{2,4}b', 'ab aab aaab aaaaabb')) 打印结果: ['aab', 'aaab', 'aaaab']
a|b匹配a或者b
print(re.findall('a|b','alex_sb ale123_sb wusir12_sb wusir_sb ritian_sb')) 打印结果: ['a', 'b', 'a', 'b', 'b', 'b', 'a', 'b']
print(re.findall('alex|太白|wusir', 'alex太白wusiraleeeex太太白odlb')) 打印结果: ['alex', '太白', 'wusir', '太白']
()匹配括号内的表达式,也表示一个组,分组
print(re.findall('([a-z]+)_sb','alex_sb ale123_sb wusir12_sb wusir_sb ritian_sb')) 打印结果: ['alex', 'wusir', 'ritian']
()制定一个规则,将满足规则的结果匹配出来,只显示括号里面的
print(re.findall('(.*?)_sb', 'alex_sb wusir_sb 日天_sb')) 打印结果 ['alex', ' wusir', ' 日天']
print(re.findall('compan(y|ies)','Too many companies have gone bankrupt, and the next one is my company')) 打印结果: ['ies', 'y'] 分组() 中加入?: 表示将整体匹配出来而不只是()里面的内容 print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company')) 打印结果: ['companies', 'company']
混合使用
.* 贪婪匹配 从头到尾(.代表任意字符,*匹配0个或多个左边的字符,那就是有0个或多个. 那只要是a开头,b结尾的字符串都符合要求)
print(re.findall('a.*b', 'ab aab a*()b')) 打印结果: ['ab aab a*()b']
.*? 此时的?不是对左边的字符进行0次或者1次的匹配,而只是针对.*这种贪婪匹配的模式进行一种限定:告知他要遵从非贪婪匹配 推荐使用!
print(re.findall('a.*?b', 'ab a1b a*()b, aaaaaab')) 打印结果: ['ab', 'a1b', 'a*()b', 'aaaaaab']
常用方法
re.search 查找
只要找到第一个就返回,返回的是一个包含匹配信息的对象,该对象可以用group()方法显示出来
import re s = re.search('alex','alex sb sb alex 日天') ##这是个对象 print(s.group()) 打印结果: alex
re.match 查找
查找的内容必须在开头,否则就返回None
s = re.match('alex','alex sb alex sb sb alex 日天') print(s.group()) 打印结果: alex
re.split 分割
可以按照任意字符分割
print(re.split('[ ::,;;,]','alex wusir,日天,太白;女神;肖锋:吴超')) 打印结果: ['alex', 'wusir', '日天', '太白', '女神', '肖锋', '吴超']
re.sub替换
s = re.sub('小红','小黄','小红和小兰,明天要跟小明一起去郊游,但是小红不想去') print(s) 打印结果: 小黄和小兰,明天要跟小明一起去郊游,但是小黄不想去
最后如果加上数字,代表替换的次数,如果次数超出字符串出现的次数,则返回所有
s = re.sub('小红','小黄','小红和小兰,明天要跟小明一起去郊游,但是小红不想去',1) print(s) 打印结果: 小黄和小兰,明天要跟小明一起去郊游,但是小红不想去
obj=re.compile('\d{2}')
obj = re.compile('\d{2}') print(obj.search('abc123eeee').group()) #12 print(obj.findall('abc123eeee')) #['12'],重用了obj 打印结果: 12 ['12']
re.finditer
返回一个存放结果的迭代器
ret = re.finditer('\d','123day788add') print(ret.__next__().group()) print([i.group() for i in ret]) 打印结果: 1 ['2', '3', '7', '8', '8']
命名分组
ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
?P是可以对组进行命名
ret = re.search("<(?P<tag_name1>\w+)>\w+</(?P=tag_name1)>","<h1>hello</h1>") print(ret.group('tag_name1')) print(ret.group()) 打印结果: h1 <h1>hello</h1>