正则表达式 & re
2018-11-20 03:25:35来源:博客园 阅读 ()
本节主要内容:
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 匹配数字 \n 匹配?个换?符 \t 匹配?个制表符 \b 匹配?个单词的结尾 ^ 匹配字符串的开始 $ 匹配字符串的结尾 \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.转义
在正则表达式中, 有很多有特殊意义的是元字符, ?如\n和\s等,如果要在正则中匹 配正常的"\n"?
不是"换?符"就需要对"\"进?转义, 变成'\\'.在python中, ?论是正则表达式, 还 是待匹配的内容, 都
是以字符串的形式出现的, 在字符串中\也有特殊的含义, 本身还需要转 义. 所以如果匹配?次"\n", 字
符串中要写成'\\n', 那么正则?就要写成"\\\\n",这样就太麻烦了. 这个时候我们就?到了r'\n'这个概念,
此时的正则是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)+"\n") f.close()
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:python技巧 一等函数
- Python连载30-多线程之进程&线程&线程使用 2019-08-13
- python学习-53 正则表达式 2019-08-13
- Python连载25-函数tell&write&writeline$&a 2019-07-24
- Python连载24-函数list&read&seek 2019-07-24
- python中time.strftime不支持中文,报错UnicodeEncodeError: 2019-07-24
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash