1. 程式人生 > >PYTHON03 - re模組 網路程式設計和socket模組

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