一、re模块
1.1 正则表达式
1.1.1 正则表达式
1.匹配单个字符
2.匹配一组字符
3.其他元字符
附: [ ^ ]:出现在中括号开头表示的是取反
4.贪婪匹配
1. *、+和?都是贪婪匹配操作符,在其后加上?可以取消
其贪婪匹配行为
2. 正则表达式匹配对象通过groups函数获取子组
>>> import re
>>> data='my number is: 15270203397'
>>> m=re.search('.+(\d+)',data)
>>> print(m.groups())
('7',)
>>> m=re.search('.+?(\d+)',data)
>>> print(m.groups())
('15270203397',)
1.1.2 核心函数和方法
1.match函数
尝试用正则表达式模式从字符串的开头匹配,如果匹配成功,则返回一个匹配对象;否则返回None
扫描二维码关注公众号,回复: 3653332 查看本文章
>>> import re
>>> m=re.match('foo', 'food') #成功匹配
>>> print(m)
<_sre.SRE_Match object;span=(0,3),match='foo'>
>>>
>>> m=re.match(‘foo’,‘seafood’) #未能匹配
>>> print(m)
None
2.search函数
在字符串中查找正则表达式模式的第一次出现,如果匹配成功,则返回一个匹配对象;否则返回None
>>> import re
>>> m = re.search('foo','food')
>>> print(m)
<_sre.SRE_Match object; span=(0,3), match='foo'>
>>>
>>> m = re.search(‘foo’,‘seafood’) #可以匹配在字符中间的模式
>>> print(m)
<_sre.SRE_Match object; span=(3,6), match='foo'>
3.group方法
使用match或search匹配成功后,返回的匹配对象可以通过group方法获得匹配内容
>>> import re
>>> m=re.match('foo','food')
>>> print(m.group())
foo
>>> m = re.search('foo', 'seafood')
>>> m.group()
'foo'
4.findall方法
在字符串中查找正则表达式模式的所有(非重复)出现;返回一个匹配对象的列表
>>> import re
>>> m=re.search('foo', 'seafood is food')
>>> print(m.group()) #search只匹配模式的第一次出现
foo
>>>
>>> m=re.findall(‘foo’,‘seafood is food’) #获得全部的匹配项
>>> print(m)
['foo', 'foo']
5.finditer函数
与findall()函数有相同的功能,但返回的不是列表而是迭代器;对于每个匹配,该迭代器返回一个匹配对象
>>> import re
>>> m= re.finditer('foo', 'seafood is food')
>>> print(m)
>>> for item in m:
... print(item.group())
...
foo
foo
6. split方法
1. 根据正则表达式中的分隔符把字符分割为一个列表,并返回成功匹配的列表
2. 字符串也有类似的方法,但是正则表达式更加灵活
>>> import re #使用 .和 - 作为字符串的分隔符
>>> mylist=re.split('\.|-','hello-world.data')
>>> print(mylist)
['hello','world','data']
7. sub方法
把字符串中所有匹配正则表达式的地方替换成新的字符串
mysub=re.sub('X','lijun','Hi X,ARE YOU X?') print(mysub)
print(mysub)
8.compile方法
1. 对正则表达式模式进行编译,返回一个正则表达式对象
2. 不是必须要用这种方式,但是在大量匹配的情况下,可以提升效率
patt=re.compile('f..')
m=patt.search('food is goodfood')
print(m.group())
1.1.3 分析apache访问日志
编写一个apche日志分析脚本
1. 统计每个客户端访问apache服务器的次数
2. 将统计信息通过字典的方式显示出来
3. 分别统计客户端是Firefox和MSIE的访问次数
4. 分别使用函数式编程和面向对象编程的方式实现
import re
def count_numbers(file,patten):
pat=re.compile(patten)
#定义一个存放统计信息的字典
pat_dict={}
with open(file) as fobj:
for line in fobj:
patResult=pat.search(line)
if patResult: #匹配到返回对象,匹配不到返回None
key=patResult.group() #把匹配到正则的对象负责给key
pat_dict[key]=pat_dict.get(key,0)+1
return pat_dict
if __name__ == '__main__':
log_file='/root/PycharmProjects/Python08/access_log'
ip='^(\d{1,3}\.){3}\d{1,3}'
count_result=count_numbers(log_file,ip)
print(count_result)
二、socket模块
2.1 C/S架构
2.1.1 什么是C/S架构
Client/Server 是客户端服务器端的架构
2.1.2 套接字
套接字是一种具有“通讯端点”概念的计算机网络数据结构
2.1.3 面向连接与无连接
1. 无论你使用哪一种地址家族,套接字的类型只有两种。一种是面向连接的套接字,另一种是无连接的套接字
2. 面向连接的主要协议就是传输控制协议TCP,套接字类型为SOCK_STREAM
3. 无连接的主要协议是用户数据报协议UDP,套接字类型为SOCK_DGRAM
4. python中使用socket模块中的socket函数实现套接字的创建
2.2 socket函数与方法
2.2.1 创建TCP服务器
• 创建TCP服务器的主要步骤如下:
1. 创建服务器套接字:s = socket.socket()
2. 绑定地址到套接字:s.bind()
3. 启动监听:s.listen()
4. 接受客户连接:s.accept()
5. 与客户端通信:recv()/send()
6. 关闭套接字:s.close()
2.2.2 编写一个TCP服务器
1. 服务器监听在0.0.0.0的12345端口上
2. 收到客户端数据后,将其加上时间戳后回送给客户端
3. 如果客户端发过来的字符全是空白字符,则终止与客户端的连接
import socket
host='' # 空串意思是0.0.0.0
port=1234 # 端口号,应该大于1024
addr=(host,port)
#1.创建服务器套接字
s=socket.socket() # 默认用的是AF_INET和SOCK_STREAM
# 默认情况下,系统会为程序保留端口号1分钟,1分钟内关闭再启动将报错:端口已占用
# 加上以下的选项,程序可以停止后立即再运行起来
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#2.绑定地址到套接字
s.bind(addr)
#3.启动监听
s.listen(1) # 数字表示可以有多少客户端排队等待服务
while True:
# 4.接受客户端连接
cli_sock, cli_addr = s.accept()
print('客户端地址:', cli_addr)
while True:
#5.设置最多一次读1024个字节
data=cli_sock.recv(1024).decode()
if data.strip()==b'quit':
break
print(data)
#6.发送数据给客户端
#cli_sock.send(b'Hello!\r\n')
rdata=input('> ')+'\r\n'
cli_sock.send(rdata.encode())
cli_sock.close()
s.close()
2.2.3 创建TCP客户端
• 创建TCP客户端的步骤主要如下:
1. 创建客户端套接字:cs = socket.socket()
2. 尝试连接服务器:cs.connect()
3. 与服务器通信:cs.send()/cs.recv()
4. 关闭客户端套接字:cs.close()
2.2.4 创建TCP时间戳客户端
• 编写一个TCP客户端
1. 连接服务器的12345
2. 接收用户从键盘上的输入
3. 发送接收到的字符串给服务器
import socket
host='176.130.10.21'
port=12345
addr=(host,port)
c=socket.socket()
c.connect(addr)
while True:
data=input('> ')+'\r\n'
data=data.encode()
c.send(data)
if data.strip() == b'quit':
break
rdata=c.recv(1024).decode() #将byte转成str类型
print(rdata,end='')
c.close()
2.2.5 创建UDP服务器
• 创建UDP服务器的主要步骤如下:
1. 创建服务器套接字:s = socket.socket()
2. 绑定服务器套接字:s.bind()
3. 接收、发送数据:s.recvfrom()/ss.sendto()
4. 关闭套接字:s.close()
2.2.6 创建UDP时间戳服务器
• 编写一个UDP服务器
1. 服务器监听在0.0.0.0的12345端口上
2. 收到客户端数据后,将其加上时间戳后回送给客户端
import socket
from time import strftime
host=''
port=12345
addr=(host,port)
s=socket.socket(type=socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(addr)
while True:
#1.接受来自客户端的数据,这些数据是byte类型的
data,cli_addr=s.recvfrom(1024)
#2.把data转换成str类型
data=data.decode()
print(data)
#3.给data打上时间戳的标记,并发送给客户端
sdata='[%s] %s' % (strftime('%Y-%m-%d %H:%M:%S'),data)
s.sendto(sdata.encode(),cli_addr)
s.close()
2.2.7 创建UDP客户端
• 创建UDP客户端的步骤主要如下:
1. 创建客户端套接字:cs = socket.socket()
2. 与服务器通信:cs.sendto()/cs.recvfrom()
3. 关闭客户端套接字:cs.close()
2.2.8 创建UDP时间戳客户端
• 编写一个UDP客户端
1. 连接服务器的12345
2. 接收用户从键盘上的输入
3. 发送接收到的字符串给服务器
import socket
host='176.130.10.21'
port=12345
addr=(host,port)
#1.创建客户端套接字
c=socket.socket(type=socket.SOCK_DGRAM)
c.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
while True:
data=input('> ')+'\r\n'
if data.strip() == 'quit':
break
#2.向服务器端发送数据
c.sendto(data.encode(),addr)
#3.接收服务端发送过来的数据
data=c.recvfrom(1024)[0]
print(data.decode(),end='')
c.close()
2.
tar -cvzf