用Python3對QQ匯出的文字聊天記錄進行整理。
阿新 • • 發佈:2019-02-11
三個月沒看QQ群了。
群裡有同學分享的近期答辯注意事項,於是乎想把近期QQ聊天記錄從頭到尾過一遍。
匯出聊天記錄文字,發覺上萬行的文字,這麼讀效率有點低,所以用python整理了一下。
這個是整理前的(手機端QQ聊天記錄匯出後的txt檔案):
這個是整理後的:
附上程式碼:
2016.12.2 加了個自動換行的程式碼,避免單行過長。
2018.1.30 根據lch1251680944、qq_20408711反饋,修正正則表示式
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import re import codecs script_name = "QQ聊天記錄整理" # 1、通過正則語句,提取出所有的記錄頭和記錄內容兩個陣列。一條記錄頭對應一條記錄內容,所以兩個陣列長度應該相等。 # 2、處理記錄內容 # 2.1、windows的換行為'\r\n',單'\n'體現不出換行效果。手機端匯出的記錄有的換行是\n,需要替換一下。 # 2.2、記錄頭放在了每條記錄末行後面,為了記錄頭整齊美觀,需要計算一下記錄頭前補多少空格。windows記事本顯示中文字元佔兩格,英文佔1格,而python中文字元長度是卻是1,如果想要顯示整齊,還需要計算一下,然後補齊空格數。補齊後記錄頭距離行首位置為100的整數倍。 # 3、讀和寫檔案的時候注意編碼轉換 def length_w(text): '''計算字串在windows記事本中的實際顯示長度''' # 取文字長度,中文按2格計算。 length = len(text) # 取其長度(中文字元長度為1,英文1) utf8_length = len(text.encode('utf-8')) # 取其長度(中文長3,英文1) length = int((utf8_length-length)/2)+length # 按(中文2英文1)計算長度 # 這個寫法實際上還是有問題的,有些特殊字元會導致計算長度和實際顯示長度不一致。所以下面計算換行問題的程式碼中換了另一種寫法,避免因特殊字元導致每行實際顯示長度超出限定值,雖然還是不精確,但是不會超出限定值。 # 比如: # '°'在記事本中顯示佔2格,b'\xc2\xb0'utf-8編碼長度為2。 # '�'在記事本中顯示佔1格,b'\xef\xbf\xbd'utf-8編碼長度為3。 # ''在記事本中顯示佔2格,b'\x01'utf-8編碼長度為1。(特殊字元無法顯示) # 至於特殊'\t'製表符最好最開始就用四個空格替換掉,避免其自動縮排帶來的影響 return length def chinese_linefeed(text,limit): '''中英文混合排版,限制單行長度,超出長度換行''' text_format= '' # 結果變數,初始化 text = text.replace('\t',' ') text = text.replace('\r\n','\n') text_arr = text.split('\n') # 按行分割文字 for line in text_arr: # 逐行處理 text_format+='\r\n' num = 0 # 長度計數變數,初始化 for i in line: # 從該行第一個字元起計算長度 # 中文長度為2 # asc2碼(英文及其字元等)長度為1 # 其他長度為2(一些特殊) if i >= u'\u4e00' and i <= u'\u9fa5': char_len=2 elif i >= u'\u001c' and i <= u'\u00ff': char_len=1 else: char_len=2 # 累計長度小於limit,直接儲存至結果變數,計數變數累加 # 累計長度大於limit,換行後再儲存,計數變數重置 if num+char_len<=limit: text_format+=i num+=char_len else: text_format+='\r\n'+i num=char_len return text_format.strip() # QQ聊天記錄手機端匯出文字 filepath = r'C:\Users\waterd\Desktop\QQ群聊天記錄.txt' # 讀取檔案 fp = codecs.open(filepath,'r','utf-8') txt = fp.read() fp.close() re_pat = r'20[\d-]{8}\s[\d:]{7,8}\s+[^\n]+(?:\d{5,11}|@\w+\.[comnet]{2,3})\)' # 正則語句,匹配記錄頭 log_title_arr = re.findall(re_pat, txt) # 記錄頭陣列['2016-06-24 15:42:52 張某(40**21)',…] log_content_arr = re.split(re_pat, txt) # 記錄內容陣列['\n', '\n選修的\n\n', '\n就怕這次…] log_content_arr.pop(0) # 剔除掉第一個(分割造成的冗餘部分) # 陣列長度 l1 = len(log_title_arr) l2 = len(log_content_arr) print('記錄頭數: %d\n記錄內容: %d'%(l1,l2)) if l1==l2: # 整理後的記錄 log_format = '' # 開始整理 for i in range(0,l1): title = log_title_arr[i] # 記錄頭 content = log_content_arr[i].strip() # 刪記錄內容首尾空白字元 content = content.replace('\r\n','\n') # 記錄中的'\n',替換為'\r\n' content = content.replace('\n','\r\n') content = chinese_linefeed(content,100) # 每行過長自動換行 lastline = content.split('\r\n')[-1] # 取記錄內容最後一行 length = length_w(lastline) # 取其長度 space = (100-(length%100))*' ' if length%100!=0 else ''# 該行記錄頭前補空格,變整齊為100整數倍;餘數為0則不用補空格 log_format += content + space + '['+title+']\r\n'# 拼接合成記錄 # 寫到檔案 fp = codecs.open(filepath+'format.txt','w','utf-8') fp.write(log_format) fp.close() print("整理完畢~^_^~") else: print('記錄頭和記錄內容條數不匹配,請修正程式碼')