1. re模块的基础方法
# import re # regex(正则表达式)
# compile
# re.compile(pattern[, flags])
# 作用:将正则表达式 pattern 编译为正则表达式对象,可用于使用其 match() 和search() 方法进行匹配。
# ret = re.compile(pattern), res = ret.findall(string)
# (等价于)
# ↓↓
# res = re.findall(pattern, string)
# flags定义包括:
# re.I:忽略大小写
# re.L:表示特殊字符集 w, W, , B, s, S 依赖于当前环境
# re.M:多行模式
# re.S:’ . ’并且包括换行符在内的任意字符(注意:’ . ’不包括换行符)
# re.U: 表示特殊字符集 w, W, , B, d, D, s, S 依赖于 Unicode 字符属性数据库
# 1. 查找方法
# findall(pattern,string,flags = 0): 匹配所有,每一项都是列表中的一个元素 # ret = re.findall('d+','sdadsa172节食加胡斐928') # 正则表达式,待匹配的字符串,flag # ret = re.findall('d','sdadsa172节食加胡斐928') # 正则表达式,待匹配的字符串,flag # print(ret) # search(pattern,string,flags = 0): 只匹配从左到右的第一个,得到的不是直接的结果,而是一个变量,通过这个变量的group方法来获取结果 # 如果没有匹配到,会返回None,使用group会报错 # ret = re.search('d+','sddsa172节食加胡斐928') # print(ret) # 返回的是内存地址,这是一个正则匹配的结果 # print(ret.group()) # 通过ret.group()获取真正的结果 # # ret = re.search('d', "orweirjuqhnqd") # print(ret) # None # print(ret.group()) # 报错 # # ret = re.search('d+','sddsa172节食加胡斐928') # if ret: # 如果ret不是None(False) # print(ret.group()) # 通过ret.group()获取真正的结果 # match: 从头开始匹配,相当于search中的正则表达式加上一个^ # ret = re.match('d+','172sdadsa节食加胡斐928') # 相当于 ret = re.serach('^d+','sdadsa172节食加胡斐928') # print(ret) # <re.Match object; span=(0, 3), match='172'> # print(ret.group()) # 172 # 2. 替换方法 # 字符串处理的扩展: 切割 替换 # split() # s = 'alex|taibai|egon|' # print(s.split('|')) # ['alex', 'taibai', 'egon', ''] #
# split(pattern, string, maxsplit=0, flags=0) # s = 'alex83taibai40egon25' # ret = re.split('d+',s) # print(ret) # ['alex', 'taibai', 'egon', ''] # sub(pattern, repl, string, count=0, flags=0) # 谁 新的 原内容 替换次数 # ret = re.sub('d+','H','alex83taibai40egon25',1) # print(ret) # alexHtaibai40egon25 # subn(pattern, repl, string, count=0, flags=0) 返回一个元组,第二个元素是替换的次数 # ret = re.subn('d+','H','alex83taibai40egon25') # print(ret) # ('alexHtaibaiHegonH', 3)
2. re模块的进阶
# re模块的进阶: 时间/空间 # compile 节省你使用正则表达式解决问题的时间 # 编译 正则表达式 编译成字节码, 在多次使用的过程中 不会多次编译(一次编译,多次使用) # ret = re.compile("d+") # 已经完成编译了,存在内存. # print(ret) # res = ret.findall('alex83taibai40egon25') # print(res) # res = ret.search('sdadsa172节食加胡斐928') # print(res.group()) # finditer 节省你使用正则表达式解决问题的空间/内存(利用迭代器) # ret = re.finditer('d+','alex83taibai40egon25') # print(ret) # ret是迭代器,打印出来是:<callable_iterator object at 0x000001D5128B5320> # for i in ret: # print(i.group())
3. 基础方法总结
# findall 返回列表,找所有的匹配项(从大段的内容中找到匹配的项目) # search 如果匹配就返回一个变量,通过group取值匹配到的第一个值,不匹配就返回None,group会报错(表单验证) # match 相当于search的正则表达式中加了一个'^' # spilt 返回列表,按照这正则规则切割,默认匹配到的内容就会被切掉 # sub/subn 替换,按照正则规则去寻找要被替换的内容,subn返回元组,第二个值是替换的次数 # compile 编译一个正则表达式,用这个结果去search match findall finditer 能够节省时间 # finditer 返回一个迭代器,所有的结果都在这个迭代器中,需要通过循环+group的形式取值 能够节省空间/内存 # 程序的优化(3点): # 1.简化人的操作(更少的代码做更多的事) # 2.节省时间 # 3.节省空间/内存
4. 关于分组(使用分组的两种情况)
1. 对于正则表达式来说,有些时候我们需要进行分组,来整体的约束某一组字符出现的次数 (.[w]+)? 2. 对于python语言来说,分组可以帮助你更好更精准的找到你真正需要的内容 <(w+)>(w+)</(w+)> (1) search-->分组索引 (2) findall-->分组优先显示 (3) 取消findall中的分组优先显示效果 (4) spilt-->分组显示切割符 import re s = '<a>wahaha</a>' # 标签语言 html 网页 (1) 分组在search中的用法:取分组中的内容(索引从1开始) ret = re.search('<(w+)>(w+)</(w+)>', s) # 所有的结果(不写参数或者写0) print(ret.group()) # <a>wahaha</a> # 数字参数代表的是对应分组中的内容(表示索引:索引从1开始) print(ret.group(1)) # a print(ret.group(2)) # wahaha print(ret.group(3)) # a 用法: 在search中分组可以被索引,索引从1开始,索引0表示匹配的全部结果,索引数字几,就表示匹配到第几个分组中的内容 (2) 分组在findall中的用法:也可以取分组中的内容(优先显示) ret = re.findall('(w+)', s) print(ret) # ['a', 'wahaha', 'a'] ret = re.findall('>(w+)<', s) print(ret) # ['wahaha'] 这里优先显示分组中的内容 用法: 在findall中的分组表示优先显示分组中的内容,可以使一个可以是多个. (3) 用?:取消findall中的分组优先 语法:(?:正则表达式) 如果我们在正则中已经用分组(括号)来约束了某一组字符出现的次数,这时拿到 python中的re模块findall方法中来用, 打印出来的和你想要的结果不一样, 原因是优先显示了分组中的内容. 那么我们如何在findall中取消分组的优先显示的效果呢? # 取消分组优先(?:正则表达式) 只用于findall # 取消优先之前 ret = re.findall('d+(.d+)?', '1.234*4.3') print(ret) # ['.234', '.3'] # 用?:取消分组优先之后 ret = re.findall('d+(?:.d+)?', '1.234*4.3') print(ret) # ['1.234', '4.3'] (4) 分组在spilt中显示切割符(类似于优先显示) # 普通显示只显示切割后的结果 ret = re.split('d+', 'alex83taibai40egon25') print(ret) # ['alex', 'taibai', 'egon', ''] # 用分组后也显示分隔符 ret = re.split('(d+)', 'alex83taibai40egon25') print(ret) # ['alex', '83', 'taibai', '40', 'egon', '25', '']
5. 分组命名及使用
1. 分组命名 (?P<名字>)正则表达式 s = '<a>wahaha</a>' ret = re.search('>(?P<con>w+)<', s) print(ret.group(1)) # wahaha print(ret.group('con')) # wahaha 2. 使用 在我们做爬虫时, 会拿到许多标签.如果我只想要某一个标签,怎么办? 比如: 我想得到<a>..</a>这个标签里的内容 # 方法1(判断是否相等) s = '<a>wahaha</a> <b>dasdfa<b>' pattern = '<(w+)>(w+)</(w+)>' ret = re.search(pattern, s) if ret.group(1) == ret.group(3): print(ret.group()) # <a>wahaha</a> # 方法2(用分组命名) # 使用前面的分组,要求使用这个名字的分组和前面同名分组中的内容匹配的必须一致 pattern = '<(?P<tab>w+)>(w+)</(?P=tab)>' ret = re.search(pattern, s) print(ret.group()) # <a>wahaha</a>