正则表达式
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
符号 | 解释 | 示例 | 说明 |
---|---|---|---|
. | 匹配任意字符 | b.t | 可以匹配bat / but / b#t / b1t等 |
\w | 匹配字母/数字/下划线 | b\wt | 可以匹配bat / b1t / b_t等 但不能匹配b#t |
\s | 匹配空白字符(包括\r、\n、\t等) | love\syou | 可以匹配love you |
\d | 匹配数字 | \d\d | 可以匹配01 / 23 / 99等 |
\b | 匹配单词的边界 | \bThe\b | |
^ | 匹配字符串的开始 | ^The | 可以匹配The开头的字符串 |
$ | 匹配字符串的结束 | .exe$ | 可以匹配.exe结尾的字符串 |
\W | 匹配非字母/数字/下划线 | b\Wt | 可以匹配b#t / b@t等 但不能匹配but / b1t / b_t等 |
\S | 匹配非空白字符 | love\Syou | 可以匹配love#you等 但不能匹配love you |
\D | 匹配非数字 | \d\D | 可以匹配9a / 3# / 0F等 |
\B | 匹配非单词边界 | \Bio\B | |
[] | 匹配来自字符集的任意单一字符 | [aeiou] | 可以匹配任一元音字母字符 |
[^] | 匹配不在字符集中的任意单一字符 | [^aeiou] | 可以匹配任一非元音字母字符 |
* | 匹配0次或多次 | \w* | |
+ | 匹配1次或多次 | \w+ | |
? | 匹配0次或1次 | \w? | |
{N} | 匹配N次 | \w{3} | |
{M,} | 匹配至少M次 | \w{3,} | |
{M,N} | 匹配至少M次至多N次 | \w{3,6} |
Python提供了re模块来支持正则表达式相关操作,下面是re模块中的核心函数。
函数 | 说明 |
---|---|
compile(pattern, flags=0) | 编译正则表达式返回正则表达式对象 |
match(pattern, string, flags=0) | 用正则表达式匹配字符串 成功返回匹配对象 否则返回None |
search(pattern, string, flags=0) | 搜索字符串中第一次出现正则表达式的模式 成功返回匹配对象 否则返回None |
split(pattern, string, maxsplit=0, flags=0) | 用正则表达式指定的模式分隔符拆分字符串 返回列表 |
sub(pattern, repl, string, count=0, flags=0) | 用指定的字符串替换原字符串中与正则表达式匹配的模式 可以用count指定替换的次数 |
fullmatch(pattern, string, flags=0) | match函数的完全匹配(从字符串开头到结尾)版本 |
findall(pattern, string, flags=0) | 查找字符串所有与正则表达式匹配的模式 返回字符串的列表 |
finditer(pattern, string, flags=0) | 查找字符串所有与正则表达式匹配的模式 返回一个迭代器 |
purge() | 清除隐式编译的正则表达式的缓存 |
re.I / re.IGNORECASE | 忽略大小写匹配标记 |
re.M / re.MULTILINE | 多行匹配标记 |
import re
# 使用 findall 找到所有匹配的子串
pattern = re.compile('foo') #编译正则表达式返回正则表达式对象
matches = re.findall(pattern, 'foobar foo baz')
print(matches) # 输出: ['foo', 'foo']pattern = re.compile('foo')
match = re.search(pattern, 'foobar foo baz') # 使用 search 查找第一个匹配
if match:print(match.group()) # 输出: foo# 使用 match 检查字符串是否以模式开始
pattern = re.compile('foo')
match = re.match(pattern, 'foobar')
if match:print(match.group()) # 输出: foo# 使用 sub 替换所有匹配的子串
pattern = re.compile('foo')
new_string = re.sub(pattern, 'bar', 'foobar foo baz')
print(new_string) # 输出: barbar bar baz
def valid():qq = input('请输入QQ号: ')res = re.match(r'^[1-9]\d{4,11}$', qq)if res:print('合规号')else:print('输入qq无效')
valid()
图形界面
GUI是图形用户界面的缩写,Python默认的GUI开发模块是tkinter(在Python 3以前的版本中名为Tkinter),从这个名字就可以看出它是基于Tk的,Tk是一个工具包,最初是为Tcl设计的,后来被移植到很多其他的脚本语言中,它提供了跨平台的GUI控件。
Tkinter
import tkinter
import tkinter.messagebox
def Tkinter_test():flag = True# 修改标签上的文字def change_label_text():nonlocal flagflag = not flagcolor, msg = ('black', 'Hello, world!')\if flag else ('green', 'Goodbye, world!')label.config(text=msg, fg=color)def confirm_to_quit(): # 确认退出if tkinter.messagebox.askokcancel('温馨提示', '确定要退出吗?'):top.quit()top = tkinter.Tk() # 创建顶层窗口top.geometry('300x200') # 设置窗口大小top.title('小游戏') # 设置窗口标题# 创建标签对象label = tkinter.Label(top, text='Hello, world!', font='Arial -30', fg='red')label.pack(expand=1) #你想让这个Label占据更多的空间,你可以设置expand=True或者expand=1panel = tkinter.Frame(top) # 创建一个装按钮的容器# 创建按钮对象button1 = tkinter.Button(panel, text='修改', command=change_label_text)button1.pack(side='left')button2 = tkinter.Button(panel, text='退出', command=confirm_to_quit)button2.pack(side='right')panel.pack(side='bottom')tkinter.mainloop() # 开启主事件循环
if __name__ == '__main__':Tkinter_test()
turtle绘图
import turtle# 设置屏幕
screen = turtle.Screen()
screen.bgcolor("white")
screen.title('turtle_text')
screen.setup(600,600)# 创建画笔
pen = turtle.Turtle()
pen.pencolor('red') #画笔颜色
pen.fillcolor('yellow')
pen.width(5) #设置线宽
pen.speed(5) #设置笔移动的速度(速度值是1-10逐渐变快;0 对应的速度最
pen.back(100) #控制笔后退指定距离,坐标原点在画布的中心
# 绘制五角星
for i in range(5): pen.forward(250) #控制笔前进指定距离pen.right(144) #向右旋转指定角度
turtle.done() # 等待用户关闭窗口
网络编程
网络编程是指利用计算机网络进行信息交流的编程。它涉及到多个计算机之间的通讯和数据传输,包括通过网络连接进行数据交换、远程服务器访问、网络协议实现等内容。计算机网络是独立自主的计算机互联而成的系统的总称,组建计算机网络最主要的目的是实现多台计算机之间的通信和资源共享。
TCP/IP
实现网络通信的基础是网络通信协议,这些协议通常是由(IETF)制定的。所谓“协议”就是通信计算机双方必须共同遵从的一组约定,例如怎样建立连接、怎样互相识别等,网络协议的三要素是:语法、语义和时序。构成今天使用的Internet的基础的是TCP/IP协议族,所谓协议族就是一系列的协议及其构成的通信模型,通常也把这套东西称为TCP/IP模型。与国际标准化组织发布的OSI/RM这个七层模型不同,TCP/IP是一个四层模型,自底向上依次是:网络接口层、网络层、传输层和应用层。
TCP全称传输控制协议,它是基于IP提供的寻址和路由服务而建立起来的负责实现端到端可靠传输的协议,之所以将TCP称为可靠的传输协议是因为TCP向调用者承诺了三件事情:1)数据不传丢不传错(利用握手、校验和重传机制可以实现)。2)流量控制(通过滑动窗口匹配数据发送者和接收者之间的传输速度)3)拥塞控制(通过RTT时间以及对滑动窗口的控制缓解网络拥堵)。
IP通常被翻译为网际协议,它服务于网络层,主要实现了寻址和路由的功能。接入网络的每一台主机都需要有自己的IP地址,IP地址就是主机在计算机网络上的身份标识。计算机网络上有大量的被我们称为' 路由器 '的网络中继设备,它们会存储转发发送到网络上的数据分组,让从源头发出的数据最终能够找到传送到目的地通路,这项功能就是所谓的路由。
基于HTTP访问
HTTP是超文本传输协议,requests是一个基于HTTP协议来使用网络的第三库,pip install requests
检索下载豆瓣top前25的电影jpg图片
from threading import Thread
import requests # 导入requests模块,用于向网页发送请求
from bs4 import BeautifulSoup # 导入BeautifulSoup,用于解析网页内容# 继承Thread类创建自定义的线程类
class DownloadHanlder(Thread):def __init__(self, url):super().__init__()self.url = urldef run(self):imgUrl = self.url.attrs["src"]imgAlt = self.url.attrs["alt"]res = requests.get(imgUrl) # 将链接添加进requests.get()中,赋值给res# 使用.content属性将响应消息转换成图片数据,赋值给imgimgPic = res.contentwith open(f"./{imgAlt}.jpg", "wb") as fp:fp.write(imgPic)def load():# 定义网页地址url = f"https://movie.douban.com/top250?start=25&filter="# 定义headers,用于存储请求头中的参数,这里只需要设置User-Agent参数,将自己伪装成浏览器headers = {"User-Agent": "Mozilla/5.0"}response = requests.get(url, headers=headers) # 向网页发起请求html = response.text # 使用.text属性获取网页的内容,并赋值给html# 使用BeautifulSoup()传入变量html和解析器lxml,赋值给soupsoup = BeautifulSoup(html, "lxml")# 使用find_all()查询soup中所有的class="pic"的节点,赋值给content_allcontent_all = soup.find_all(class_="pic")# for循环遍历content_all列表for content in content_all:# 使用find()查询content中的name="img"的节点,赋值给imgimg = content.find(name="img")DownloadHanlder(img).start()if __name__ == '__main__':load()
套接字编程
套接字就是一套用C写成的应用程序开发库,主要用于实现进程间通信和网络编程,在网络应用开发中被广泛使用。在Python中也可以基于套接字来使用传输层提供的传输服务,并基于此开发自己的网络应用。实际开发中使用的套接字可以分为三类:流套接字(TCP套接字)、数据报套接字和原始套接字。
TCP套接字
所谓TCP套接字就是使用TCP协议提供的传输服务来实现网络通信的编程接口。在Python中可以通过创建socket对象并指定type属性为SOCK_STREAM来使用TCP套接字。由于一台主机可能拥有多个IP地址,而且很有可能会配置多个不同的服务,所以作为服务器端的程序,需要在创建套接字对象后将其绑定到指定的IP地址和端口上。这里的端口并不是物理设备而是对IP地址的扩展,用于区分不同的服务。
msg->发送->server 接收, 回复
client.py
import socketsocket_client = socket.socket() # 创建socket对象
socket_client.connect(('192.168.56.1', 6789)) # 连接到服务器
while True:send_msg = input("请输入要发送给服务端的消息:")if send_msg == 'exit':breaksocket_client.send(send_msg.encode("UTF-8")) # 发送消息# 接收消息recv_data = socket_client.recv(1024).decode("UTF-8") # 1024是缓冲区大小,一般1024,recv是阻塞式print(f"服务端回复的消息是:{recv_data}")
socket_client.close() # 关闭连接
server.py
import socketsocket_server = socket.socket()
socket_server.bind(('192.168.56.1', 6789))
# 监听端口
socket_server.listen(512)
# 等待客户端连接,accept方法返回二元元组(连接对象, 客户端地址信息)
print(f"服务端已开始监听,正在等待客户端连接...")
conn, address = socket_server.accept()
print(f"接收到了客户端的连接,客户端的信息:{address}")# 接受客户端信息,使用客户端和服务端的本次连接对象,而非socket_server
while True:data: str = conn.recv(1024).decode("UTF-8") # 接收消息print(f"客户端发来的消息是:{data}")msg = input("请输入你要回复客户端的消息:") # 回复消息if msg == 'exit':breakconn.send(msg.encode("UTF-8")) # encode将字符串编码为字节数组对象
conn.close() # 关闭连接
socket_server.close()
UDP套接字
传输层除了有可靠的传输协议TCP之外,还有一种非常轻便的传输协议叫做用户数据报协议,简称UDP。TCP和UDP都是提供端到端传输服务的协议,二者的差别就如同打电话和发短信的区别,后者不对传输的可靠性和可达性做出任何承诺从而避免了TCP中握手和重传的开销,所以在强调性能和而不是数据完整性的场景中(例如传输网络音视频数据),UDP可能是更好的选择。