PYTHON03 - re模組 網路程式設計和socket模組
一、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
>>> 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