正则表达式 & re
Posted af1y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式 & re相关的知识,希望对你有一定的参考价值。
本节主要内容:
1.正则表达式
2.re模块的使用
一.正则表达式
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),
计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式是对字符串操作的一种逻辑公式.我们一般使用正则表达式对字符串进行匹配和过滤.使用正则的优缺点:
优点: 灵活,功能性强,逻辑性强.
缺点:上手难.
工具:各大文本编辑器一般都有正则匹配功能.也可去 http://tool.chinaz.com/regex 进行在线测试.
正则表达式有普通字符和元字符组成. 普通字符包含大小写字母,数字. 在匹配普通字符的时候我们直接写就可以了.
元字符:元字符才是正则表达式的灵魂.
1.字符组
字符组用[]括起来. 在[]中出现的内容会被匹配.例如:[abc] 匹配a或b或c
如果字符组的内容过多还可以使用-,例如: [a-z] 匹配a到z之间的所有字? [0-9] 匹配所有阿拉伯数字
2.简单元字符
常用的元字符:
. 匹配除换?符以外的任意字符 w 匹配字?或数字或下划线 s 匹配任意的空?符 d 匹配数字 匹配?个换?符 匹配?个制表符 匹配?个单词的结尾 ^ 匹配字符串的开始 $ 匹配字符串的结尾 W 匹配?字?或数字或下划线 D 匹配?数字 S 匹配?空?符 a|b 匹配字符a或字符b () 匹配括号内的表达式,也表示?个组 [...] 匹配字符组中的字符 [^...] 匹配除了字符组中字符的所有字符
3.量词
* 重复零次或更多次 + 重复?次或更多次 ? 重复零次或?次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次
4.惰性匹配和贪婪匹配
在量词中的*,+,{}都属于贪婪匹配.就是尽可能多的匹配到结果
str: 麻花藤昨天让英雄联盟关服了 reg: 麻花藤.* 此时匹配的是整句话
在使用.*后面如果加上?则是尽可能少的匹配.表示惰性匹配
str: 麻花藤昨天让英雄联盟关服了 reg: 麻花藤.*? 此时匹配的是 麻花藤 str: <div>胡辣汤</div> reg: <.*> 结果: <div>胡辣汤</div> str: <div>胡辣汤</div> reg: <.*?> 结果: <div> </div> str: <div>胡辣汤</div> reg: <(div|/div*)?> 结果: <div> </div>
.*?x思维特殊含义,找到下一个x为止
str: abcdefgxhijklmn reg: .*?x 结果:abcdefgx
5.分组
在正则中使用()进行分组.括号中的内容表示一个元字符.
例如:我们要匹配?个相对复杂的?份证号. ?份证号分 成两种. 老的?份证号有15位.
新的?份证号有18位. 并且新的?份证号结尾有可能是x.我们可以使用下列正则:
给出以下正则: ^[1-9]d{13,16}[0-9x]$ ^[1-9]d{14}(d{2}[0-9x])?$ ^([1-9]d{16}[0-9x]|[1-9]d{14})$
6.转义
在正则表达式中, 有很多有特殊意义的是元字符, ?如 和s等,如果要在正则中匹 配正常的" "?
不是"换?符"就需要对""进?转义, 变成‘\‘.在python中, ?论是正则表达式, 还 是待匹配的内容, 都
是以字符串的形式出现的, 在字符串中也有特殊的含义, 本身还需要转 义. 所以如果匹配?次" ", 字
符串中要写成‘\n‘, 那么正则?就要写成"\\n",这样就太麻烦了. 这个时候我们就?到了r‘ ‘这个概念,
此时的正则是r‘\n‘就可以了.
二. re模块
re模块是python提供的一套关于处理正则表达式的模块.核心功能有四个:
1.findall 查找所有.返回list
import re lst = re.findall("m", "mai le fo len, mai ni mei a !") print(lst) # [‘m‘, ‘m‘, ‘m‘] lst = re.findall(r"d+", "5点之前, 要给我500万") print(lst) # [‘5‘, ‘500‘]
2.search 会进行匹配.但是如果匹配到了第一个结果.就会返回这个结果.如果匹配不到search返回的则是None
ret = re.search(r‘d‘, ‘5点之前. 你要给我5000万‘).group() print(ret) # 5
3.match只能从字符串的开头进行匹配,匹配不到会报错
ret = re.match(‘a‘, ‘abc‘).group() print(ret) # a
4.finditer 和 findall差不多.只不过返回的是迭代器
it = re.finditer("m", "mai le fo len, mai ni mei!") for el in it: print(el.group()) # 依然需要分组
5.其他操作
import re
ret = re.split(‘[ab]‘, ‘qwerafjbcd‘) # 先按‘a‘分割得到‘qwer‘和‘fjbcd‘,在对‘qwer‘和‘fjbcd‘分别按‘b‘分割
print(ret) # [‘qwer‘, ‘fj‘, ‘cd‘]
ret = re.sub(r"d+", "_sb_", "alex250taibai250wusir250ritian38") # 把字符串中的数字换成__sb__
print(ret) # alex_sb_taibai_sb_wusir_sb_ritian_sb_
ret = re.subn(r"d+", "_sb_", "alex250taibai250wusir250ritian38") # 将数字替换成‘__sb__‘,返回元组(替换的结果,替换了多少次)
print(ret) # (‘alex_sb_taibai_sb_wusir_sb_ritian_sb_‘, 4)
obj = re.compile(r‘d{3}‘) # 将正则表达式编译成为?个 正则表达式对象, 规则要匹配的是3个数字
ret = obj.search(‘abc123eeee‘) # 正则表达式对象调?search, 参数为待匹配的字符串
print(ret.group()) # 结果: 123
# 爬虫重点
obj = re.compile(r‘(?P<id>d+)(?P<name>e+)‘) # 从正则表达式匹配的内容每个组起名字
ret = obj.search(‘abc123eeee‘) # 搜索
print(ret.group()) # 结果: 123eeee
print(ret.group("id")) # 结果: 123 # 获取id组的内容
print(ret.group("name")) # 结果: eeee # 获取name组的内容
6.两个坑
注意:在re模块中和我们在线测试工具中的结果可能是不一样的,
import re ret = re.findall(‘www.(baidu|oldboy).com‘, ‘www.oldboy.com‘) print(ret) # [‘oldboy‘] 这是因为findall会优先把组里的内容的匹配结果返回,如果想要匹配结果,取消权限即可 ret = re.findall(‘www.(?:baidu|oldboy).com‘, ‘www.oldboy.com‘) print(ret) # [‘www.oldboy.com‘]
split里的坑.
import re ret = re.split("d+","eva3egon4yuan") print(ret) # 结果: [‘eva‘, ‘egon‘, ‘yuan‘] ret = re.split("(d+)","eva3egon4yuan") print(ret) # 结果: [‘eva‘, ‘3‘, ‘egon‘, ‘4‘, ‘yuan‘] #在匹配部分加上()之后所切出的结果是不同的, #没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项, #这个在某些需要保留匹配部分的使?过程是?常重要的。
简易爬虫:
爬取豆瓣top250里的内容
from urllib.request import urlopen import re obj = re.compile(r‘<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?导演: ‘ r‘(?P<daoyan>.*?) .*?<span class="rating_num" property=‘ r‘"v:average">(?P<fen>.*?)</span>.*?<span>(?P<ren>.*?)人评价</span>‘, re.S) def getContent(url): content = urlopen(url).read().decode("utf-8") return content def parseContent(content): it = obj.finditer(content) # 把页面中所有匹配的内容进行匹配. 返回迭代器 for el in it: yield { "name":el.group("name"), "daoyan":el.group("daoyan"), "ren":el.group("ren"), "fen":el.group("fen") } for i in range(10): url = "https://movie.douban.com/top250?start=%s&filter=" g = parseContent(getContent(url)) f = open("movie.txt", mode="a", encoding="utf-8") for el in g: f.write(str(el)+" ") f.close()
以上是关于正则表达式 & re的主要内容,如果未能解决你的问题,请参考以下文章