正则表达式
今日内容概要
- 正则表达式之字符组
- 正则表达式之量词
- 正则表达式之特殊符号
- 正则表达式之贪婪与非贪婪
- python正则模块之re
字符组
"""
字符组默认匹配方式式挨个挨个匹配
"""
[0123456789] 匹配0到9任意一个数
[0-9] 匹配0到9任意一个数(缩写)
[a-z] 匹配到26个小写英文字母
[A-Z] 匹配到26个大写英字母
[0-9a-zA-Z] 匹配数字或者小写字母或者大写字母
ps:字符内所有的数据默认都是或的关系
特殊符号
""" 特殊符号默认匹配方式式挨个挨个匹配 """
\w 匹配数字字母下划线
\d 匹配数字
\s 匹配空白字符
\n 匹配换行符
\t 匹配制表符
\W 匹配非数字字母下划线
\D 匹配非数字
\S 匹配非空白符
^ 匹配开头
. 匹配非换行符
$ 匹配结尾
a|b 匹配a或者 b
[..] 匹配字符组里的字符
[^das] 匹配das就是非列的数字
() 分组 就是为了清晰 对匹配没有影响
量词
量词(默认的都是贪婪模式)
* 非贪婪模式 零次 贪婪模式 无数次
+ 非贪婪模式 1次 贪婪模式 无数次
? 非贪婪 0 次 贪婪 1次
在 * 和 + 后面可以让他们变为 非贪婪,在自己后面也可以让自己变得非贪婪
{n} n个
{n,} 至少n个 多了不限制
{n,m} 至少n个 至多 m个
{}
正则表达式实战建议
1.编写校验用户身份证号的正则
def is_id(text):
"""验证身份证"""
import re
res = re.finditer("^[1-9]\d{13,16}[0-9x]$", text)
# res = re.finditer("^[1-9]\d{14}(\d{2}[0-9x])?$", text)
# res = re.finditer("^([1-9]\d{16}[0-9x]|[1-9]\d{14})$", text)
return res
2.编写校验邮箱的正则
# \w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}
# def is_email(text):
# """校验邮箱"""
# import re
# res = re.finditer("\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}", text)
# return res
3.编写校验用户手机号的正则(座机、移动)
# def is_phon_num(text):
# """验证手机号码"""
# import re
# # 手机号
# # res = re.finditer("0?(13|14|15|17|18|19)[0-9]{9}", text)
# # 电话号
# res = re.finditer("[0-9-()()]{7,18}", text)
# return res
4.编写校验用户qq号的正则
# def is_QQ_num(text):
# """校验QQ号码"""
# import re
# res = re.finditer("[1-9]([0-9]{5,11})", text)
# return res
ps:能够写出简单的正则 能够大致看懂复杂的正则
re模块
# 在python中常见的操作方法
# import re
# 查找所有符合正则表达式要求的数据结果直接是一个列表
# res = re.findall("a", "dsadasdfa")
# print(res) # ['a', 'a', 'a'] # 生成一个迭代器
# 结果是一个列表
# res = re.finditer("a", "dsadasdfa")
# print(res) # <callable_iterator object at 0x000001A15ABCA940>
# for i in res:
# print(i)
"""
<re.Match object; span=(2, 3), match='a'>
<re.Match object; span=(4, 5), match='a'>
<re.Match object; span=(8, 9), match='a'>
"""
# for i in res:
# print(i.group())
# a
# a
# a
# import re
# res = re.search("a", "jason apple eva")
# print(res) # <re.Match object; span=(1, 2), match='a'>
# print(res.group()) # a
# import re
# res = re.match("a", "jason apple eva")
# print(res) # None 匹配字符串的开头如果不符合后面不用看了
# res = re.match("a", "ajason apple eva")
# print(res) # <re.Match object; span=(0, 1), match='a'>
# print(res.group()) # a
# import re
# obj = re.compile("\d{3}")
# res = obj.findall("dasdsada123123")
# # print(res) # ['123', '123']
# # res = obj.findall("\w", "wdasdasdsa")
# print(res) # ['123', '123']
# import re
# # ret = re.split("[ab]", "abcd")
# # print(ret) # 先按a 切 ["","bcd"] 在按b 切 ["", "", "cd"]
#
# ret = re.sub("\d", "H", "edsad3asdd2", 1)
# print(ret) # edsadHasdd2
#
# ret = re.subn("\d", "H", "sdqdasd23423dfas")
# print(ret) # ('sdqdasdHHHHHdfas', 5)
# re模块补充说明
import re
"""1.分组优先"""
# res = re.findall("www.(baidu|oldboy).com", "www.oldboy.com")
# print(res) # ['oldboy']
"""
findall 是分组优先 就是 先打印组内的数据 就完了
"""
# res = re.findall("www.(\d)(\w.+?)(\w).com", "www.11oldboy.com")
# print(res) # [('1', '1oldbo', 'y')]
# res = re.findall("www.(?:\d)(?:\w.+?)(?:\w).com", "www.11oldboy.com")
# print(res) # [('1', '1oldbo', 'y')]
# """
# 要用 ?: 来降低组的优先级
# """
# 分组别名
res = re.search("www.(?P<content>baidu|oldboy)(?P<hei>.com)","www.oldboy.com")
print(res.group()) # www.oldboy.com
print(res.group("content")) # oldboy
print(res.group("hei")) # .com
print(res.group(0)) # www.oldboy.com
print(res.group(1)) # oldboy
print(res.group(2)) # .com]
网络爬虫简介
网络爬虫:通过编写代码模拟浏览器发送请求获取数据并按照自己指定的要求筛选出想要的数据
作业
思考红牛分公司数据爬取
import re
import requests
ret = requests.get("http://www.redbull.com.cn/about/branch")
text1 = ret.text
# print(text1)
# text = """<li data-longitude="120.189905" data-latitude="30.263377" data-title="红牛杭州分公司" data-describe="杭州市上城区庆春路29号远洋大厦11楼A座"><h2>红牛杭州分公司</h2><p class="mapIco">杭州市上城区庆春路29号远洋大厦11楼A座</p><p class="mailIco">310009</p><p class="telIco">0571-87045279/7792</p></li>"""
# res = re.findall(r"""data-longitude=.*|data-latitude=.*|data-title=.*|data-describe=.*""", text1)
# res = re.finditer(r"""data-longitude=.*|data-latitude=.*|data-title=.*|data-describe=.*>?""", text1)
# res = re.findall(r"data-title=.*", text1)
# res1 = re.findall(r"data-longitude=.*", text1)
# res2 = re.findall(r"data-latitude=.*", text1)
# res3 = re.findall(r"data-title=.*", text1)
# res4 = re.findall(r"data-describe=.*", text1)
# print(res.__next__().group())
# print(res.__next__().group())
# print(res.__next__().group())
# print(res.__next__())
# print(res.__next__())
# print(res.__next__())
# res = re.findall("mapIco.*", text1)
# print(res)
# res = re.findall("telIco.*", text1)
# print(res)
res = re.finditer(r'''data-longitude=.*|data-latitude=.*|data-title=.*|mapIco.*|telIco.*''', text1)
# print(res)
# local_city = res.__next__().group()
# name_city = res.__next__().group()
# adss_city = res.__next__().group()
# local_city_list = local_city.strip().split(" ")
# local_city_longitude = local_city_list[0].split("=")[-1]
# local_city_latitude1 = local_city_list[1].split("=")[-1]
# name_city_list = name_city.strip().split("=")
# print(local_city_longitude,local_city_latitude1)
# print(name_city_list[-1])
# print(adss_city.split(">")[1].split("<")[0])
# print(adss_city.split(">")[3].split("<")[0])
# print(adss_city.split(">")[5].split("<")[0])
def num(x, y, z, ):
local_city = x.group()
name_city = y.group()
adss_city = z.group()
local_city_list = local_city.strip().split(" ")
local_city_longitude = local_city_list[0].split("=")[-1]
local_city_latitude1 = local_city_list[1].split("=")[-1]
name_city_list = name_city.strip().split("=")
# print(local_city_longitude, local_city_latitude1, end="")
# print(name_city_list[-1], end="")
# print(adss_city.split(">")[1].split("<")[0])
# print(adss_city.split(">")[3].split("<")[0])
# print(adss_city.split(">")[5].split("<")[0])
print(f'经纬度:{local_city_longitude},{local_city_latitude1} 公司名称:{name_city_list[-1]}\n 地址:{adss_city.split(">")[1].split("<")[0]} 邮编:{adss_city.split(">")[3].split("<")[0]} 联系方式:{adss_city.split(">")[5].split("<")[0]}' )
print()
cont = 0
cont_list = []
for i in res:
cont_list.append(i)
if len(cont_list) == 3:
num(*cont_list)
cont_list = []
# print(res.__next__())
# print(res.__next__())
# print(res3)
# print(res4)

浙公网安备 33010602011771号