Python2与编码问题

前言

最近接了做字幕的兼职,自己总结了一套效率比较高的流程,但其中有一步需要将混在一起的中文行和英文行分开,所以想到了借助Python脚本来解决。

本来觉得是个没那么复杂的问题,就是检测某一行是否包括中文即可,不过由于对编码问题的不熟悉,花了不少功夫。

(建议大家尽快转用Python3,此类问题会少很多。。。)

正文

编码溯源

1.为了处理英文字符,产生了ASCII码。 
2.为了处理中文字符,产生了GB2312。 
3.为了处理各国字符,产生了Unicode。注意Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。 
4.为了提高Unicode存储和传输性能,产生了UTF-8,它是Unicode的一种实现形式。

UTF-8与BOM

Windows下使用UTF-8编码默认会在文件头加BOM(byte order mark),它是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。

尽管 Unicode 标准允许在 UTF-8 中使用 BOM,但它并不是必要的。特别地,UTF-8 的网页代码不应使用 BOM。

微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。

而使用Notepad++可以将文本文件的编码格式转换为无BOM的UFT-8编码格式。

系统编码

系统的默认编码有所不同(这里指控制台显示的编码):Linux默认UTF-8,Windows(简体中文)默认GB2312。

因此直接用Windows控制台输出UTF-8编码格式的中文会出现乱码,就是因为编译码方式不同,导致解析错误。

源码中的编码

Python2会将整个python脚本中的内容当做ASCII码去处理,因此在文件头部加入一行编码声明如:

# -*-coding:utf8-*-

这样,Python在处理这个脚本时,会用UTF-8的编码去处理整个脚本,就能够正确的解析中文字符了。

字符串中的编码

Python2中的字符串有str和Unicode两种类型。

str类型的字符串都有一定的编码方式,如ASCII、GBK、UTF-8等等,而Unicode即为无编码格式的计算机存储符号。

通过encode和decode函数可以在两者间进行转换

可以观察到UNICODE编码的串输出时在整个字符串前带一个'u'的前缀,每个UNICODE符也各自含有一个'\u'的开头。

查资料知基本汉字的UNICODE范围在4E00-9FA5之间,简略地使用这个范围便足以满足我们的需求。

参考资料

字符编码笔记:ASCII,Unicode 和 UTF-8(强烈推荐)

彻底搞懂Python的字符编码

Window 编码 UTF-8 BOM 说明

附代码

# -*-coding:utf8-*-

#首先需将中英文字幕文件编码格式修改为UFT-8无BOM编码格式,并将其放置在所确定的路径
#转换结束后再将文件修改回UFT-8编码格式,或者不转好像也行 ^_^

def have_Chinese(word):
    for ch in word.decode('utf-8'):
        if u'\u4e00' <= ch <= u'\u9fff':
            return True
    return False
#路径修改为翻译字幕所在路径
path = "D:\\Desktop\\"
#翻译字幕文件名
file = path+"Subtitles.txt"
#视频题目
title = path+"Video"
with open(file,'r') as f:
    lines = f.readlines()
    Cn=[]
    Eng=[]
    for line in lines:
        if len(line) <= 8:  #这意味着空码,包含时间码和换行符
            Cn.append(line)
            Eng.append(line)
            continue
        if have_Chinese(line):  #行内包含中文则视为中文字幕
            Cn.append(line)
        else:
            Eng.append(line)  #否则为英文字幕
            
with open(title+'.txt','w') as res_Eng:
    for line in Eng:
        res_Eng.write(line)


with open(title+'_CN.txt','w') as res_Cn:
    for line in Cn:
        res_Cn.write(line)

猜你喜欢

转载自blog.csdn.net/Tele_Anti_Nomy/article/details/83473630
今日推荐