Python之正则表达式
我们在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
很可能你使用过Windows/Dos下用于文件查找的通配符(wildcard),也就是和?。如果你想查找某个目录下的所有的Word文档的话,你会搜索.doc。在这里,*会被解释成任意的字符串。和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂——比如你可以编写一个正则表达式,用来查找所有以0开头,后面跟着2-3个数字,然后是一个连字号“-”,最后是7或8位数字的字符串(像010-12345678或0376-7654321)。
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
可以通过下面简单的代码认识一下简单的正则表达式:
import re
def main():
number = input('请输入数字:')
m1 = re.match(r'^\d{3}$', number)
# 任意三位数字
m2 = re.match(r'^14\d{3}$', number)
# 14开头后接任意三位数字
m3 = re.match(r'^\w{2}\d{3}$', number)
# 任意两个字符(大小写字母和符号)及三个数字
if m1 or m2 or m3:
print('这是一个有效字符串')
else:
print('这是一无效字符串')
if __name__ == '__main__':
main()
代码/语法 | 说明 |
---|---|
常用的元字符 | |
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
常用的限定符 | |
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
常用的反义代码 | |
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
常用分组语法 | |
(exp) | 匹配exp,并捕获文本到自动命名的组里 |
(?exp) | 匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp) |
(?:exp) | 匹配exp,不捕获匹配的文本,也不给此分组分配组号 |
(?=exp) | 匹配exp前面的位置 |
(?<=exp) | 匹配exp后面的位置 |
(?!exp) | 匹配后面跟的不是exp的位置 |
(? | 匹配前面不是exp的位置 |
(?#comment) | 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 |
懒惰限定符 | |
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
re.match函数
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
re.search方法
re.search 扫描整个字符串并返回第一个成功的匹配。
re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
compile 函数
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
# 输入正确的用户名及QQ号码
import re
def main():
username = input('请输入用户名:')
qq = input('请输入QQ:')
# m1 = re.match(r'^[0-9a-zA-Z]{6,20}', username)
patternl = re.compile(r'^[0-9a-zA-Z]{6,20}')
m1 = patternl.match(username)
if not m1:
print('请输入有效用户名')
m2 = re.match(r'^[1-9]\d{4,11}$', qq)
if not m2:
print('请输入有效QQ号')
if m1 and m2:
print('你输入的信息是有效的!')
if __name__ == '__main__':
main()
Python 的re模块提供了re.sub用于替换字符串中的匹配项。
import re
def main():
# substitute -- 替换
sentence = 'hello world!'
pure = re.sub('[ ]|[h]', '*', sentence, flags=re.IGNORECASE)
# 把hello world! 中的空格和h替换成*符号。
# flags=re.IGNORECASE 标记,忽略大小写
print(pure)
if __name__ == '__main__':
main()
Python 之多进程 / 多线程
1、进程:操作系统分配内存的基本单位,进程之间的内存是相互隔离的,互相之间交换数据是IPC机制
2、线程:一个进程划分为多个线程,线程是进程的执行单元,也是操作系统分配CPU基本单元(线程越多,占用CPU越多,调度CPU的可能越大)
使用多进程多线程的情况:
1、提升性能(一个任务执行时间过长,为了提升执行效率,改善程序性能,提升运行时间,考虑用多线程多进程。)
2、改善用户体验
多进程
multiprocessing模块
multiprocessing模块提供了一个Process类来代表一个进程对象
# 同时打印出'pong' 和 'ping'
from multiprocessing import Process
count = 0
def output(string):
global count
while count < 10:
print(string, end=' ', flush=True)
count += 1
def main():
t1 = Process(target=output, args=('Ping', ))
t1.start()
t2 = Process(target=output, args=('Pong', ))
t2.start()
if __name__ == '__main__':
main()
# 同时调用电脑内程序
import subprocess
def main():
subprocess.call('calc')
subprocess.call('notepad')
subprocess.call('python 多进程.py')
if __name__ == '__main__':
main()
多线程
多线程类似于同时执行多个不同程序,多线程运行有如下优点:
1、使用线程可以把占据长时间的程序中的任务放到后台去处理。
2、用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
3、程序的运行速度可能加快
4、在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
创建线程的两种方式:
1、直接创建Thread对象并通过target参数指定线程启动后要执行的任务
2、继承Thread自定义线程,通过重写run方法指定线程启动后执行的任务
from threading import Thread
def output(string):
while True:
print(string, end=' ', flush=True)
def main():
t1 = Thread(target=output, args=('Ping',), daemon=True)
t1.start()
t2 = Thread(target=output, args=('Pong',), daemon=True)
# damon=True -- 将线程设置为守护器
# 守护线程 -- 不值得保留的线程 -- 其他线程如果都执行完毕了,守护线程自动结束
t2.start()
if __name__ == '__main__':
main()
Python之网络编程
网络服务器
from socket import socket
from threading import Thread
def main():
class ClientHandler(Thread):
def __init__(self, client):
super().__init__()
self._client = client
def run(self):
try:
while True:
try: # 查询异常
data = self._client.recv(1024) # 接收消息
# self._client.send(data) 发送消息
if data.decode('utf-8') == 'byebye': # 如果说了byebye,主动断开连接
clients.remove(self._client)
self._client.close()
break
else:
for client in clients:
client.send(data)
except Exception as e:
print(e)
clients.remove(self._client) # 出故障移除
break
except Exception as e:
print(e)
server = socket() # 1创建套接字
# python命令行参数 -- sys.argv -- 替换端口(端口可变)
server.bind(('10.7.189.71', 4096)) # 2建立端口
server.listen(512) # 3监听
clients = [] # 5创建列表,容纳每一个客户端
while True:
# server.accept() 接收用户消息(阻塞式)返回一个元组
curr_client, addr = server.accept() # 4接收用户
print(addr[0], '连接到服务器.')
clients.append(curr_client) # 6
ClientHandler(curr_client).start() # 7创建线程、使用线程
if __name__ == '__main__':
main()
客户端
from socket import socket
from threading import Thread
def main():
class RefreshScreenThread(Thread):
def __init__(self, client):
super().__init__()
self._client = client
def run(self):
while running:
data = self._client.recv(1024)
print(data.decode('utf-8'))
nickname = input('请输入你的昵称: ')
myclient = socket()
myclient.connect(('10.7.189.71', 4096))
running = True
RefreshScreenThread(myclient).start()
while running:
content = input('请发言: ')
if content == 'byebye':
myclient.send(content.encode('utf-8'))
running = False
else:
msg = nickname + ': ' + content
myclient.send(msg.encode('utf-8'))
if __name__ == '__main__':
main()
python发送邮件
from smtplib import SMTP
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
def main():
sender = SMTP('smtp.163.com')
sender.login('邮箱', '**邮箱的SMTP码')
message = MIMEMultipart()
message['Subject'] = '请查收'
text_msg = MIMEText('附件中有本月相关数据请查收', 'plain', 'utf-8')
message.attach(text_msg)
att2 = MIMEText(open('123.xls', 'rb').read(), 'base64', 'utf-8')
att2['Content-Type'] = 'application/octet-stream' # 注意mime类型
att2['Content-Disposition'] = 'attachment; filename=456.xls'
message.attach(att2)
sender.sendmail('发件者邮箱', ['发送至邮箱'],
message.as_string())
print('发送完成!')
if __name__ == '__main__':
main()