Python 自動識別並批量轉換文本文件編碼

来源:https://www.cnblogs.com/hahaa/archive/2023/03/24/17240446.html
-Advertisement-
Play Games

如題,很簡單,就是先用chardet 庫識別文件編碼,解碼之後再輸出成目標編碼。算是個偶爾能用上的小工具,要用的時候萬一沒有就很難受的那種,比如,網上下載了別人的項目文件,一打開全是亂碼…… 代碼 加了比較詳細的註釋~~ 看懂的要求應該不高,平時用過Python,知道幾個常用庫就行。 from pa ...


如題,很簡單,就是先用chardet 庫識別文件編碼,解碼之後再輸出成目標編碼。算是個偶爾能用上的小工具,要用的時候萬一沒有就很難受的那種,比如,網上下載了別人的項目文件,一打開全是亂碼……

代碼

加了比較詳細的註釋~~ 看懂的要求應該不高,平時用過Python,知道幾個常用庫就行。

from pathlib import Path
import chardet
import re

def text_file_encoding_convert(f: Path, target_encoding: str, *, dry_run=False) -> (bool, str, float):
    ''' 轉換單個文件到目標編碼
    @param  f                   文件路徑
    @param  target_encoding     目標編碼,比如urf-8
    @param  dry_run             為True 時不實際修改源文件

    @return  返回三個值分別為(是否成功,估計的源文件編碼,估計的把握)
    '''
    target_encoding = target_encoding.lower()    # python 的標準編碼名稱都是小寫
    raw = f.read_bytes()
    result = chardet.detect(raw)
    encoding = result["encoding"].lower()     # chardet 估計出來的編碼名稱
    confidence = result["confidence"]    # 估計的把握
    flag = True

    # 下麵的單次for 迴圈用來避免重覆寫return 語句,break 後統一跳到最後return
# Python學習交流裙 872937351
for _d( ̄_ ̄)b_ in (1,): if encoding == target_encoding or encoding == "ascii" and target_encoding == "utf-8": # 目標編碼和源編碼相同時不用做處理。utf-8 編碼和ASCII 相容,原編碼為ASCII 時轉換到utf-8 不會有變化,所以也跳過 print(f"-> [NO CONVERSION NEEDED] {f.name}: {encoding} ==> [ {target_encoding} ]") break try: text = raw.decode(encoding) except: print(f"!> Encoding err: {f.name}, detected: {encoding}, {confidence}.") flag = False break if dry_run: print(f"-> [ NO WET ] {f.name}: {encoding} ==> [ {target_encoding} ]") else: # 必須先用目標編碼轉換成位元組數組,然後按位元組寫入源文件 # 如果按文本方式寫入,就會遇到喜聞樂見的CR LF 換行問題, # 源文件中的CR LF 換行會被自動變成CR CR LF,也就是多了一堆空行。 out = text.encode(target_encoding) f.write_bytes(out) print(f"-> {f.name}: {encoding} ==> [ {target_encoding} ]") return (flag, encoding, confidence) def text_file_encoding_batch_convert( folder: Path, target_encoding: str, *, dry_run=True, recursive=False, pattern=".*(c|h|txt|cxx|cpp|hpp|hxx|csv|asm)$", skip_when_error=True, ): ''' 批量轉換一個目錄下文本文件的編碼 Python學習交流群 872937351 @param folder 目標目錄 @param target_encoding 目標編碼 @param dry_run 不實際修改源文件,避免手滑寫錯 @param recursive 包括所有子文件夾下的文件 @param pattern 基於文件名篩選文本文件的正則表達式,預設根據尾碼篩選幾種文本類型 @param skip_when_error 預設True,單個文件轉換出錯時提示並跳過,否則終止 ''' if recursive: flist = folder.rglob("*") else: flist = folder.glob("*") p = re.compile(pattern) # 把正則編譯了,之後應該能快一點 for f in flist: if not (f.is_file() and p.match(f.name)): continue ok, encoding, confidence = text_file_encoding_convert(f, target_encoding, dry_run=dry_run) if not ok: if skip_when_error: print("!> SKIP.") else: print("!> ABORT.") return

 

用法


既然是批量轉換文件,只調用第二個函數就好了,如下:

folder = Path(r"D:\Downloads\Some shit\\")
text_file_encoding_batch_convert(folder, "utf-8", recursive=True)

 

目標目錄為D:\Downloads\Some shit\,放進一個Path 對象里,作為第一個參數傳進去。第二個參數是目標編碼,第三個參數必須寫明參數名稱recursive,用來指定要不要遍歷子文件夾,預設是False,為了避免意外情況。直接這麼運行的話,輸出的信息應該類似這樣:

-> [NO WET] main.c : gb2312 ⇒ utf-8

 

[NO WET] 意思就是DRY [doge],也就是沒有實際修改源文件,只是讓你大致看看輸出信息對不對勁,實際運行的話再加一個參數:

text_file_encoding_batch_convert(folder, "utf-8", recursive=True, dry_run=False)

 

順便一說,輸出信息都是英文的,因為大伙應該都遇到過控制台輸出中文亂碼的問題,反正也沒幾個單詞。剩下兩個參數,skip_when_error 放著別管就行,沒什麼用;pattern 是匹配文件名的正則表達式,只有匹配的文件會被處理,可以自己設置;預設的正則只匹配了幾種容易遇到亂碼問題的文本文件,匹配的太多了也可能錯殺,需要的話往括弧裡加就行。

對了,上面的代碼和這篇文章一樣,使用 CC - BY SA 4.0 協議。

   
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一個新應用 房地產廣告模塊 假設需要開發一個房地產模塊,該模塊覆蓋未包含在標準模塊集中特定業務領域。 以下為包含一些廣告的主列表視圖 form視圖頂層區域概括了房產的重要信息,比如name,Property Type, Postcode等等。 列表記錄詳情頁中,第一個tab包含了房產的描述信息,比如 ...
  • 生產者消費者問題 簡介 生產者消費者模式並不是GOF提出的23種設計模式之一,23種設計模式都是建立在面向對象的基礎之上的,但其實面向過程的編程中也有很多高效的編程模式,生產者消費者模式便是其中之一,它是我們編程過程中最常用的一種設計模式。 在實際的軟體開發過程中,經常會碰到如下場景:某個模塊負責產 ...
  • 之前用過NXOpen PDM的命名空間下的類,現在記錄一下通過PDM命名空間下的類查詢Teamcenter零組件的信息,也可以用來判斷該零組件是否存在。 1-該工程為DLL工程,直接在NX界面調用,所以直接獲取NXSession。 2-查詢函數advanced用到的查詢為:__NX_STD_ANY_ ...
  • 本文已收錄至Github,推薦閱讀 👉 Java隨想錄 微信公眾號:Java隨想錄 摘要 Redis是一款性能強勁的記憶體資料庫,但是在使用過程中,我們可能會遇到Big Key問題,這個問題就是Redis中某個key的value過大,所以Big Key問題本質是Big Value問題,導致Redis ...
  • 9 月 15 日,Figma 的 CEO Dylan Field 發佈消息:今天,Figma 宣佈接受 Adobe 的收購... Adobe 以約 200 億美元收購 Figma,這也是 Adobe 該公司在其歷史上的最大一筆收購。那是什麼樣的魔力,讓 Figma 被 Adobe 收購呢?下麵以定位 ...
  • 實現Redis的database層(核心層:處理命令並返回) https://github.com/csgopher/go-redis 本文涉及以下文件: dict:定義字典的一些方法 sync_dict:實現dict db:分資料庫 command:定義指令 ping,keys,string:指令 ...
  • Antlr4 簡介 ANTLR(全名:ANother Tool for Language Recognition)是基於LL(*)演算法實現的語法解析器生成器(parser generator),用Java語言編寫,使用自上而下(top-down)的遞歸下降LL剖析器方法。由舊金山大學的Terence ...
  • 導入的文件 前端點擊上傳得到文件(MultipartFile file 【這裡是存放的臨時文件】) 本人前端用的vue3,elementui, 導入按鈕代碼 <!--導入文件 --> <el-col :span="1.5"> <el-button type="info" plain icon="el ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...