如何编写乱码修复脚本

wen 实用脚本 24

本文目录导读:

如何编写乱码修复脚本

  1. 基础乱码修复脚本
  2. 更强大的乱码修复版本
  3. 命令行版本
  4. 使用说明

我来帮你编写一个通用的乱码修复脚本,以下是一个Python实现的示例,可以处理多种常见的乱码情况:

基础乱码修复脚本

import chardet
import os
from pathlib import Path
def detect_encoding(file_path):
    """检测文件编码"""
    with open(file_path, 'rb') as f:
        raw_data = f.read()
        result = chardet.detect(raw_data)
        return result['encoding']
def fix_file_encoding(file_path, target_encoding='utf-8'):
    """
    修复文件编码乱码
    """
    try:
        # 检测原始编码
        original_encoding = detect_encoding(file_path)
        if not original_encoding:
            print(f"无法检测编码: {file_path}")
            return False
        # 读取文件
        with open(file_path, 'rb') as f:
            raw_data = f.read()
        # 尝试解码
        try:
            text = raw_data.decode(original_encoding)
        except:
            # 如果检测的编码不正确,尝试常见编码
            for encoding in ['utf-8', 'gbk', 'gb2312', 'latin-1', 'cp936']:
                try:
                    text = raw_data.decode(encoding)
                    break
                except:
                    continue
            else:
                print(f"无法解码文件: {file_path}")
                return False
        # 写入新编码
        with open(file_path, 'w', encoding=target_encoding) as f:
            f.write(text)
        print(f"成功修复: {file_path}")
        return True
    except Exception as e:
        print(f"修复失败 {file_path}: {str(e)}")
        return False
def batch_fix_encoding(folder_path, extensions=['.txt', '.csv', '.html', '.xml']):
    """批量修复文件夹中的文件"""
    folder = Path(folder_path)
    fixed_count = 0
    failed_count = 0
    for ext in extensions:
        for file_path in folder.rglob(f'*{ext}'):
            if file_path.is_file():
                if fix_file_encoding(file_path):
                    fixed_count += 1
                else:
                    failed_count += 1
    print(f"\n总结: 成功修复 {fixed_count} 个文件, 失败 {failed_count} 个文件")
# 使用示例
if __name__ == "__main__":
    # 修复单个文件
    fix_file_encoding("example.txt")
    # 批量修复文件夹
    batch_fix_encoding("./乱码文件夹")

更强大的乱码修复版本

import chardet
import os
import codecs
from pathlib import Path
class EncodingFixer:
    def __init__(self):
        self.common_encodings = [
            'utf-8', 'gbk', 'gb2312', 'gb18030',
            'big5', 'latin-1', 'cp1252', 'shift_jis',
            'euc-kr', 'iso-8859-1'
        ]
    def detect_encoding_smart(self, file_path):
        """智能检测编码"""
        with open(file_path, 'rb') as f:
            raw_data = f.read()
        # 使用 chardet 检测
        result = chardet.detect(raw_data)
        if result['confidence'] > 0.7:
            return result['encoding']
        # 如果置信度低,尝试其他编码
        for encoding in self.common_encodings:
            try:
                raw_data.decode(encoding)
                return encoding
            except:
                continue
        return None
    def fix_garbled_text(self, text):
        """修复常见的乱码模式"""
        # 常见乱码映射
        garbled_map = {
            '锘挎': '无',  # UTF-8 BOM 导致的乱码
            '绗�': '第',
            '涓�': '中',
            '浜�': '人',
            '鍦�': '地',
            '涓�': '中',
            '绗�': '第',
        }
        for garbled, correct in garbled_map.items():
            text = text.replace(garbled, correct)
        return text
    def fix_file(self, input_path, output_path=None, encoding=None):
        """
        修复文件乱码
        """
        try:
            # 检测编码
            detected_encoding = self.detect_encoding_smart(input_path)
            encoding = encoding or detected_encoding
            if not encoding:
                print(f"无法确定编码: {input_path}")
                return False
            # 读取并修复
            with open(input_path, 'rb') as f:
                raw_data = f.read()
            # 去除BOM
            if raw_data.startswith(codecs.BOM_UTF8):
                raw_data = raw_data[3:]
            # 解码
            try:
                text = raw_data.decode(encoding)
            except UnicodeDecodeError:
                # 尝试用忽略错误的方式解码
                text = raw_data.decode(encoding, errors='ignore')
            # 修复常见乱码
            text = self.fix_garbled_text(text)
            # 确定输出路径
            output_path = output_path or input_path
            # 创建备份
            if input_path == output_path:
                backup_path = input_path + '.bak'
                with open(backup_path, 'wb') as f:
                    f.write(raw_data)
                print(f"已创建备份: {backup_path}")
            # 写入修复后的内容(UTF-8)
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(text)
            print(f"成功修复: {input_path}")
            return True
        except Exception as e:
            print(f"修复失败 {input_path}: {str(e)}")
            return False
    def batch_fix(self, folder_path, output_folder=None, extensions=None):
        """批量修复文件夹中的文件"""
        if extensions is None:
            extensions = ['.txt', '.csv', '.html', '.xml', '.json', '.log', '.md']
        folder = Path(folder_path)
        if output_folder:
            output_folder = Path(output_folder)
            output_folder.mkdir(parents=True, exist_ok=True)
        results = {'success': 0, 'fail': 0}
        for ext in extensions:
            for file_path in folder.rglob(f'*{ext}'):
                if file_path.is_file():
                    if output_folder:
                        rel_path = file_path.relative_to(folder)
                        output_path = output_folder / rel_path
                        output_path.parent.mkdir(parents=True, exist_ok=True)
                    else:
                        output_path = None
                    if self.fix_file(file_path, output_path):
                        results['success'] += 1
                    else:
                        results['fail'] += 1
        print(f"\n批量修复完成:")
        print(f"成功: {results['success']} 个文件")
        print(f"失败: {results['fail']} 个文件")
        return results
# 使用示例
if __name__ == "__main__":
    fixer = EncodingFixer()
    # 修复单个文件并保存到新位置
    fixer.fix_file("乱码.txt", "修复后.txt")
    # 直接修复原文件(会自动创建备份)
    fixer.fix_file("原始文件.txt")
    # 批量修复文件夹
    fixer.batch_fix("./输入文件夹", "./输出文件夹")

命令行版本

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""乱码修复脚本 - 命令行工具"""
import argparse
import sys
from pathlib import Path
# 导入上面的 EncodingFixer 类
def main():
    parser = argparse.ArgumentParser(description='乱码修复工具')
    parser.add_argument('path', help='文件或文件夹路径')
    parser.add_argument('-o', '--output', help='输出路径(可选)')
    parser.add_argument('-e', '--encoding', help='指定编码(可选)')
    parser.add_argument('--extensions', nargs='+', 
                       default=['.txt', '.csv', '.html', '.xml', '.log'],
                       help='处理的文件扩展名')
    parser.add_argument('--backup', action='store_true', 
                       help='是否创建备份')
    args = parser.parse_args()
    fixer = EncodingFixer()
    path = Path(args.path)
    if path.is_file():
        # 修复单个文件
        success = fixer.fix_file(
            path, 
            args.output,
            args.encoding
        )
        sys.exit(0 if success else 1)
    elif path.is_dir():
        # 批量修复文件夹
        results = fixer.batch_fix(
            path, 
            args.output,
            args.extensions
        )
        sys.exit(0 if results['fail'] == 0 else 1)
    else:
        print(f"路径不存在: {path}")
        sys.exit(1)
if __name__ == "__main__":
    main()

使用说明

安装依赖

pip install chardet

基本使用

# 1. 修复单个文件
python fix_encoding.py 乱码文件.txt
# 2. 修复并保存到新文件
python fix_encoding.py 乱码文件.txt -o 修复后.txt
# 3. 批量修复文件夹
python fix_encoding.py ./乱码文件夹 -o ./修复后文件夹
# 4. 指定编码
python fix_encoding.py 乱码文件.txt -e gbk
# 5. 指定文件类型
python fix_encoding.py ./文件夹 --extensions .txt .csv .json
# 6. 创建备份
python fix_encoding.py 乱码文件.txt --backup

注意事项

  1. 建议先处理少量文件测试效果
  2. 重要文件请先备份
  3. 不同的编码问题可能需要调整参数
  4. 对于复杂的乱码,可能需要手动处理

这个脚本可以处理大部分常见的编码乱码问题,包括UTF-8、GBK、BIG5等编码之间的转换问题。

抱歉,评论功能暂时关闭!