全民一起玩Python提高篇第八课:字符串与正则表达式(中)

懒惰搜索和捕获组

将正则表达式中的某一部分用半角圆括号括起来,就形成了一个“捕获组
如果正则表达式中包含捕获组,那么 findall 方法返回的列表中,每个元素是一个元组,对应一个匹配结果。而元组中的内容,则只包括捕获组中的文本、而不是完整的匹配结果。
如果在量词(+、*、?、{} )后面再写一个半角问号,比如 +? 、{}? 、?? 等,该量词就按照懒惰搜索原则进行匹配。所谓懒惰搜索,就是当存在多个符合条件的匹配时,选择其中最短的那一个作为匹配结果。

题目

在这里插入图片描述

import re
with open('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test1\提高篇第二十六课\python02_26_01.txt','r',encoding='utf-8') as f:
    s=f.read()
a=re.findall('第([一二三四五六七八九十百]*)回',s)
print(a)

可以用懒惰搜索来写

a=re.findall('第(.+?)回',s)

题目二

在这里插入图片描述

import re
with open('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test1\提高篇第二十六课\python02_26_01.txt', encoding='utf-8') as f:
    all_text = f.read()
result = re.findall('第(\w+)回\s+(\w+)\s+(\w+)', all_text)
for i, title1, title2 in result:
    print(i, title1, title2)

题目三

在这里插入图片描述

import re
with open('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test1\提高篇第二十六课\python02_26_01.txt', encoding='utf-8') as f:
    all_text = f.read()
result = re.findall('第(\w+)回\s+(\w+)\s+(\w+)', all_text)
for i, title1, title2 in result:
    print(i, title1[0],'......', title2[0],'......')

转义问题

转义直接加个/就行
但是正则表达式测试通过,不一定代表在Python中可以用,因为可能和Python语法冲突,比如正则表达式被写成一个Python字符串,那么其中的引号和反斜线可能会与Python中的字符串语法产生冲突、造成混乱,需要按照Python的语法规则再进行一次转义,即再打上一个反斜线

Python避免这种情况,可以使用r字符
比如 r’John’s book’ 中的 ’ ,那么该反斜线仍然被视作转义符号,而不是普通字符;
但是如果字符串末尾有一个反斜线,比如 r’abc’ ,则为语法错误;两个反斜线看做一个反斜线字符
正则表达式中的元字符 \b ,代表一个位置而不是一个字符,即“单词边界线”。该位置的一边为“文字字符”、另一边则是“非文字字符”。
所以写URL时,最好用/而不是\

题目一

匹配出所有的邮箱
张三的电话是0411-32423443,网名是Sany Zhang,电子邮箱是zhangsan@163.net。李四的网名是Lee@dalian,email是4li@263.com。王五的电话是 023-23423443,他的邮箱:500233@yahoo.com赵六的邮箱是zh_6_2020@pc6.com 。
1.邮箱的标志是@ ,@前面是字母或者是数字
[\w\d_]+@
2.后面的标志是点号,点号前面是数字或者字母
[\w\d_]+@[\w\d]+
3.这里要用转义后的点号
[\w\d_]+@[\w\d]+.
4.后面是字母
[\w\d_]+@[\w\d]+.\w+

在这里插入图片描述

题目二

抽取出Python里面的所有转义字符,也就是 “\n”、“\t”、“\b” 和 “\x”,该如何编写程序?

在Python语言中,\n代表回车符,\t代表制表符,\b代表退格符,\x用于表示16进制数字。

import re
s = r'在Python语言中,\n代表回车符,\t代表制表符,\b代表退格符,\x用于表示16进制数字。'
re.findall( r'\\\w', s)

括号

正则式中使用圆括号包含起来的部分,自动属于同一个“分组”。在分组后面使用量词,代表该组格式反复出现多次。
如果不使用分组,量词只能让前面的一个字符或字符组重复出现多次。
正则式中写有几对圆括号,最终得到的捕获组就有多少个。即使在一个匹配结果中,一对圆括号匹配出多段局部内容,捕获组中也只保留最后一段内容。
使用 (?: ) 可以创建一个非捕获组,其内容仍然被视为一个分组,但是不会被视作 “捕获组” 。
默认情况下,^ 代表被搜索的整个文本的开始位置、$ 代表整个文本的结尾位置。而如果设置启用“多行模式”,二者分到代表每一行的行首和行尾。
在Python中,只要给 findall 等函数指定可选参数 flag=re.MULTILINE 或 flag=re.M ,就可以在该正则式中启用多行模式。
正则式中可以使用 \n 代表换行符。

题目三:匹配电子邮箱

在这里插入图片描述

import re
import xlwings as xw
app=xw.App()
wb=app.books.add()
ws=wb.sheets[0]

with open(r'E:\拷贝过来的文件\全民一起玩Python\MyProject\Test2\提高篇第二十八课\python02_28_03.txt',encoding='utf-8')as f:
    s=f.read()
#print(s)
emails = re.findall(r'[\da-zA-Z]+@(?:[\da-zA-Z]+.)+[\da-zA-Z]+',s)
#匹配字母或数字,@符号,字母或者数字 或 数字或者字母
ws.range('A1').options(transpose=True).value =emails
for i in emails:
    print(i)
wb.save('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test2\提高篇第二十八课\讨论出勤情况.xlsx')
wb.close()
app.quit()

统计邮箱类别

请编写一个Python程序,统计出这200名用户使用的邮箱平台各有多少。

import re
from collections import Counter

with open(r'E:\拷贝过来的文件\全民一起玩Python\MyProject\Test2\提高篇第二十八课\python02_28_03.txt',encoding='utf-8') as f:
    s=f.read()

emails=re.findall(r'@(?:[da-z]+.)*([da-z]+.[da-z]+)',s)
for i, k in Counter(emails).items():
    print(i, k)
#引入counter来统计

网抓图片

分支符号 | 可以将两个或更多正则式以“或者”的方式连在一起,比如 “ abc|def ” ,其含义就是找到文本中所有的 abc 或者所有的 def 。分支符号也可以用在分组中,比如 “ a(cd|ef) ” ,可以匹配 acd 或 aef 。
启动“单行模式”后,点号可以匹配换行符,此时 .* 可以 匹配整段文本,否则点号不能匹配回车之类的
单行模式与多行模式分别针对不同的元字符设定,所以二者互相无关,可以同时启用。比如在findall等函数中指定 flag 参数为 re.DOTALL|re.MULTILINE ,就可以同时启用单行模式(点号可换行)与多行模式(^$代表每行首尾)。
urlopen( 网址 ) 方法返回一个 Response 类型的对象,其 read() 方法可以把该网址资源的内容(网页文本或图片、视频等)以二进制的形式,全部读入一个字节流对象(bytes)。
如果指定网址是一个图片或zip等非文本格式的文件,可以直接将读入的字节流对象保存到硬盘上,从而实现文件下载。

题目:抓取网页图片

from urllib import request
import re
import chardet
res=request.urlopen('http://mobile.zol.com.cn/')
#存网站返回值
b=res.read()
#返回的是字节流,不是字符串
c=chardet.detect(b)
#查编码方式
if str(c['encoding']).lower() =='gb2312':
    c['encoding']='gb18030'
s=b.decode(c['encoding'])

a=re.findall(r'<img.*?src="(.*?)"',s)
#读取所有图片格式的字符串
x = 1#计数器
for i in a:
    res=request.urlopen(i)
    #从网站返回值
    c=res.read()
    #读字节流
    with open(f'E:\拷贝过来的文件\全民一起玩Python\MyProject\Test2\提高篇第二十九课/图片/这是图片{x}.jpg','wb')as f:
        #取后十位作为文件名,二进制写入
        f.write(c)
    x+=1

抓了图片,又找了个批量重命名的轮子

import os
import sys
def rename():
    path='E:\拷贝过来的文件\全民一起玩Python\MyProject\Test2\提高篇第二十九课\图片'
    name='这是图片'
    startNumber='1'
   # fileType=input("请输入后缀名(如 .jpg、.txt等等):")
    fileType ='.jpeg'
    print("正在生成以"+name+startNumber+fileType+"迭代的文件名")
    count=0
    filelist=os.listdir(path)
    for files in filelist:
        Olddir=os.path.join(path,files)
        if str(Olddir)[-4:]=='.jpg':
            Newdir=os.path.join(path,name+str(count+int(startNumber))+fileType)
            os.rename(Olddir,Newdir)
            count+=1
    print("一共修改了"+str(count)+"个文件")

rename()

就得到下面的图了
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值