re模块
re模块
正则表达式引入
当我们使用手机号注册某些网站或是应用时,我们所输入的手机号都会被软件监测,检查格式是否正确,那么这个功能以我们目前学习的知识是否可以实现,答案是可以
while True: # 1.获取用户输入的手机号 phone_num = input('请输入您的手机号>>>:').strip() # 2.先判断是否是十一位 if len(phone_num) == 11: # 3.再判断是否是纯数字 if phone_num.isdigit(): # 4.判断手机号的开头 if phone_num.startswith('13') or phone_num.startswith('15') or phone_num.startswith( '17') or phone_num.startswith('18') or phone_num.startswith('19'): print('手机号码输入正确') else: print('手机号开头不对') else: print('手机号必须是纯数字') else: print('手机号必须是11位')
但是今天我们会学习到一个全新的知识——正则表达式,当我们结合正则表达式来写这个功能时
import re phone_number = input('please input your phone number: ') if re.match('^(13|14|15|18)[0-9]{9}$', phone_number): print('是合法的手机号码') else: print('不是合法的手机号码')
借助于正则表达式,我们仅仅通过几行代码就可以完成该功能
正则表达式是一门独立的技术,所有编程语言都可以使用
它的作用可以简单的概括为:利用一些特殊符号(也可以直接写需要查找的具体字符)的组合产生一些特殊的含义然后去字符串中筛选出符合条件的数据
主要作用就是筛选数据(匹配数据)那么,我们先来学习正则表达式的组成
正则表达式之字符组
正则表达式之特殊符号
. 匹配除换行符以外的任意字符
\w 匹配数字、字母、下划线
\W 匹配非数字、非字母、非下划线
\d 匹配数字
^ 匹配字符串的开头
$ 匹配字符串的结尾
两者组合使用可以非常精确的限制匹配的内容
a|b 匹配a或者b(管道符的意思是或)
() 给正则表达式分组 不影响表达式的匹配功能
[] 字符组 内部填写的内容默认都是或的关系
[^] 取反操作 匹配除了字符组里面的其他所有字符PS:上尖号在中括号内和中括号意思完全不同
正则表达式之量词
正则表达式默认情况下都是贪婪匹配>>>:尽可能多的匹配
'.' 匹配零次或多次 默认是多次(无穷次)
'+' 匹配一次或多次 默认是多次(无穷次)
'?' 匹配零次或一次 作为量词意义不大主要用于非贪婪匹配
{n} 重复n次
{n,} 重复n次或更多次 默认是多次(无穷次)
{n,m} 重复n到m次 默认是m次ps:量词必须结合表达式一起使用,不能单独出现,并且只影响左边第一个表达式
jason\d{3} 只影响\d
贪婪匹配与非贪婪匹配
所有的量词都是贪婪匹配如果想要变为非贪婪匹配只需要在量词后面加问号
待匹配的文本 <script>alert(123)</script> 待使用的正则(贪婪匹配) <.*> 请问匹配的内容 <script>alert(123)</script> 一条 # .*属于典型的贪婪匹配,使用它时结束条件一般在左右明确指定 待使用的正则(非贪婪匹配) <.*?>
正则表达式实例
re模块
re模块是python中结合正则表达式来帮我们实现一些功能的模块
import re # 常见操作方法 res = re.findall('a', 'jason apple eva') print(res) # 查找所有符合正则表达式要求的数据 结果直接是一个列表 res = re.finditer('a', 'jason apple eva') print(res) # 查找所有符合正则表达式要求的数据 结果直接是一个迭代器对象 res = re.search('a', 'jason apple eva') print(res) # <re.Match object; span=(1, 2), match='a'> print(res.group()) # a 匹配到一个符合条件的数据就立刻结束 res = re.match('a', 'jason apple eva') print(res) # None 匹配字符串的开头 如果不符合后面不用看了 print(res.group()) # 匹配开头符合条件的数据 一个就结束 obj = re.compile('\d{3}') # 当某一个正则表达式需要频繁使用的时候 我们可以做成模板 res1 = obj.findall('23423422342342344') res2 = obj.findall('asjdkasjdk32423') print(res1, res2) ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 print(ret) # ['', '', 'cd'] ret = re.sub('\d', 'H', 'eva3jason4yuan4', 1) # 将数字替换成'H',参数1表示只替换1个 print(ret) # evaHjason4yuan4 ret = re.subn('\d', 'H', 'eva3jason4yuan4') # 将数字替换成'H',返回元组(替换的结果,替换了多少次) print(ret) # ('evaHjasonHyuanH', 3)
re模块补充说明
- 分组优先
res = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com') print(res) # ['oldboy'] # findall分组优先展示:优先展示括号内正则表达式匹配到的内容 res = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com') print(res) # ['www.oldboy.com'] # ?:的作用是取消分组中优先展示的内容,但并不抹去该功能 res = re.search('www.(baidu|oldboy).com', 'www.oldboy.com') print(res.group()) # www.oldboy.com res = re.match('www.(baidu|oldboy).com', 'www.oldboy.com') print(res.group()) # www.oldboy.com # match与search不会进行优先展示
- 分组别名
res = re.search('www.(?P<content>baidu|oldboy)(?P<hei>.com)', 'www.oldboy.com') # ?P<分组的别名>,我们可以用这样的方式在分组中为分组取别名 print(res.group()) # www.oldboy.com print(res.group('content')) # oldboy 我们可以在使用过程中使用别名调用分组中优先展示内容 print(res.group(0)) # www.oldboy.com print(res.group(1)) # oldboy print(res.group(2)) # .com print(res.group('hei')) # .com # 我们也可以利用索引值来获得结果中对应的内容
爬虫简介:网络爬虫:通过编写代码模拟浏览器发送请求获取数据并按照自己指定的要求筛选出想要的数据