re模块 正则匹配
import re re.M 多行模式 位或的意思 parrterm就是正则表达式的字符串,flags是选项,表达式需要被编译,通过语法、策划、分析后卫其编译为一种格式,与字符串之间进行转换 re模块 主要为了提速,re的其他方法为了提高效率都调用了编译方法,就是为了提速 re的方法 单次匹配 re.compile 和 re.match def compile(pattern,flags=0): return _compile(pattern,flags) 可看到,re最后返回的是_compile内部方法并对其进行转换 def match(pattern,string,flags).match(string) 使用re模块 importre s ='0123abc' regx = re.compile('d') print(type(regx)) (re.match(regx,s)) <class '_sre.SRE_Pattern'> <_sre.SRE_Match object; span=(0,1),match='0'> 意思为返回一个模块为match 从头开始匹配扫描,发现匹配一次则不会再继续向下扫描执行 ) matcher = re.match(,s) #通过regex查看编译后的结果 (matcher) matcher.endpos <class '_sre.SRE_Match'> 每次运行的时候需要调用match match内部调用了编译方法,意思是说明这个是内部函数,所以compile和match的处理方式是一样的 而match本质是从头向后匹配,找到立刻返回 '[a|b]'matcher = regx.match(s) (matcher)) <class 'NoneType'> None 发现是None,match要求必须是从头开始 改进: 'a0123abc' '^[a|b]'matcher = re.match(regx,51);font-family:Monaco;">(matcher) <class '_sre.SRE_Match'> 编译后的match方法可以自己定义索引位置,但是compile没有 import re s = '0123abc' regex = re.compile('[a|b]') matcher = re.match('d',51);font-family:Monaco;">print(type(matcher)) print(matcher) matcher = regex.match(s,2) <class '_sre.SRE_Match'> search 方法 '012abc' mather = re.search('[ab]'(mather) <_sre.SRE_Match object; span=(3,4),match='a'> 可看到已匹配到a match和serach对比 match 找到第一个立即返回,位置是从3开始,直接打印,只匹配一次 search 不管从什么位置开始,找到第一个匹配的则立即返回,行为上和match差不多,只不过search是可以不定位置的 一般情况先都为先编译后使用,所以尽量少使用compile 有些情况也是第一次使用匹配的字符,所以如果明确开头是想要的,直接使用match,不然使用search频率比较高 fullmatch 全文匹配 fullmatch相当于正则匹配全场 matcher = re.fullmatch('w'matcher = regx.fullmatch(s) None None #改进: matcher = regx.fullmatch(s,45) <_sre.SRE_Match object; span=(4,5),match='a'> res= re.fullmatch('bag'(res) None 由于fullmatch属于全文匹配,所以要么必须有范围,要么必须得知其长度 '''bottlenbagbigable''' regex = re.compile(res = regex.fullmatch(s,255);font-family:Monaco;">710) #匹配完全长度 (res) <_sre.SRE_Match object; span=(7,10),match='bag'> 使用全文匹配最好: ?尽量匹配字符 ?先切片再匹配 每个字符对应索引不知,将索引获取后进行折行 able''' forkinenumerate(s): ifk[0] %8==: () end=' ') findall findall 所返回为一个列表 s = '0123abcd' regx = re.compile('^bw+') matcher = regx.findall(s,re.M) print(type(matcher)) <class 'list'> 找到所有包含b的字符 able''' rest= re.findall('b'rest['b','b','b'] regx= re.compile('^b'rest = re.findall(regx(rest) ['b'] rest = re.findall(regx,'b'] re.M SRE_FLAG_MULTILINE=8# treat target as multiline string 最少匹配一个 '0123abcd' '[ab]+') matcher= regex.findall(s) #字节调用regex方法后面跟字符串即可 matcher['ab'] 匹配非数字所有的 'D'matcher = regex.findall(s) ['a','c','d'] finditer 返回一个可迭代对象 # coding:utf-8 re # s = '''bottlenbagnbignable''' matcher = regex.finditer(s) <class 'callable_iterator'> <callable_iterator object at 0x0000000000B87128> #返回一个迭代器 迭代器可以使用next直接跑出来 for i in matcher: print(i) <_sre.SRE_Match object; span=(4,match='a'> <_sre.SRE_Match object; span=(5,6),match='b'> <_sre.SRE_Match object; span=(6,7),match='c'> <_sre.SRE_Match object; span=(7,8),match='d'> regex = re.compile('D') matcher = re.match('d',s) print(matcher.span()) (0,1) re.M 多行模式 s = '''bottlenbagnbignable''' regex = re.compile(r'^bw+',re.Mmatcher = regex.findall(s) ['bottle','bag','big'] 去掉re.M查看 s = '''bottlenbagnbignable''' regex = re.compile(r'^bw+') matcher = regex.findall(s) print(matcher) ['bottle'] 筛取以e结尾的行 import re regex = re.compile(r'^w+e$',monospace;">print(matcher) 为了避免出现问题,就用n的方式进行分割 在边界的时候指定选项re.M 匹配并替换 sub re.sub 匹配原来的字符并替换,可根据次数进行调整 将每个数字都替换为一个串字符 s = '''bottlen123nbagnbignable''' regx = re.compile('d') res = regx.sub('haha',monospace;">print(res) bottle hahahahahaha bag big able 替换一次 haha23 将big bag 替换 regx = re.compile('w+g') res = regx.sub('hh',monospace;">print(res) 返回了一个新的字符串 hh hh 使用subn print(regx.subn('ha',s)) 返回一个元组 ('bottlen123nhanhanable',2) subn会将其全部封装至一个元组中 s = '''os.path([path])''' regx = re.compile('[.]') print(type(regx)) print(regx) <class '_sre.SRE_Pattern'> re.compile('[.]') 将其替换为空格 newstr = regx.sub(' ',monospace;">print(newstr) newstr = regx.subn(' ',monospace;">os path([path]) ('os path([path])',1) 字符串分割 re.split() 可匹配模式、字符串、最大切割数 s = ''' 01 bottle 02 bag 03 big1 100 bale ''' regx = re.compile('^[sd]+') res = re.split(regx,51);font-family:Monaco;">['','bottlen02 bagn03 big1n100 balen'] 如果想去掉n 需要涉及到断言 数字之前是n regx = re.compile('s+|(?<=!w)d') res = re.split(regx,s) print(res) ['01','bottle','02','03','big1','100','bale',''] 如果使用d+的话,则数字也全部被消除 regx = re.compile('s+|(?<!w)d+') ['','',''] 筛出空格两边的数字 s+d+s+ 之前用的是断言方式,有点复杂,现在我们发现一个规律:两头都有空字符,除了第一行 对于023来讲,前有n 所以认为数字两边都有空白字符的话,则直接匹配并替换 分组 使用小括号的模式捕获的数据存在了组中 match 、search函数可以返回match对象 findall返回字符串列表 finditer返回一个个的match对象 使用group(N)方式对应分组,1-N是对应的分组,0是返回整个字符串 使用group,在match对象中加入分组会返回一个group,返回一个>=0的整数,1代表1号分组 以此类推 s = '''bottlenbagnbig1nbale''' regex = re.compile('(bwg)') matcher = regex.search(s) print(matcher.groups()) <_sre.SRE_Match object; span=(13,16),match='bag'> ('bag',) 0位整个串,如果超出的话不会报错,一直都是0 print(matcher.groups(0)) print(matcher.groups(1)) print(matcher.groups(2)) print(matcher.groups(3)) ('bag',) regex = re.compile('(bw+e)',re.M) 我们用的是search方法,所知匹配一次 查看: 0是表示匹配从b开头,,b不属于元组内,e也不是 regex = re.compile('b(w+)e',re.M) ('ottl',) 替换为findall regex = re.compile('b(w+)e') print(matcher.groups(1)) 提示: 意思为能匹配到,但是不能用列表的方式进行group(),需要自己处理 改进: 使用finditer,使用迭代器,进行循环 regex = re.compile('b(w+)(e)') matchers = regex.finditer(s) print(matchers) for matchers in matchers: print(matchers.groups()) 分组匹配的太多,我们仅需要将分组外的抛除 regex = re.compile('b(w+) (?p<TAIL>e)') groupdict 用命名则按照索引方式,用了名字照样可以用索引方式同时支持groupdict() 正则匹配练习 匹配邮箱地址 匹配邮箱地址 html标记获取文字 获取<a>标记 改进 更严谨的判断: 看到这里是w不带等号或者引号 用取非的方式获取 更复杂的实现: 通过分组取出 改进: 如果取得属性,并有引号则用引号取边界并取反 如果url后面有属性参数可以改为: 匹配一个url S 一定不出现空格的字符并至少出现1次的, 匹配身份证 判断密码强弱 凡是有非法字符在的话则替换为空,这样会缩减,并判断字符串的长度 W判断,查看是否有特殊符号,其他全是合法字符,这样的话肯定会扫描出非合法密码 获取别人最少用的_ 符号,也就是必包含它 单词统计 file_path = r'C:UsersAdministratorDesktopsample.txt' s = '''index modules | next | previous |Python 3.5.3 Documentation The Python Standard Library 11. File and Directory Access ''' regex = re.compile('[^-w]+') d = defaultdict(lambda:0) with open(file_path,'r+',encoding='utf-8') as f: for line in f: for x in re.split(regex,line): if len(x) > 0: d[x] += 1 print(sorted(d.items(),key=lambda x:x[1],reverse=True)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |