Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何确定文本的编码?_Python_Encoding_Text Files - Fatal编程技术网

Python 如何确定文本的编码?

Python 如何确定文本的编码?,python,encoding,text-files,Python,Encoding,Text Files,我收到一些经过编码的文本,但我不知道使用了什么字符集。有没有一种方法可以使用Python确定文本文件的编码?处理C#。在一般情况下,原则上不可能确定文本文件的编码。因此,没有标准的Python库可以为您做到这一点 如果您对文本文件有更具体的了解(例如,它是XML),则可能有库函数。如果您知道文件的某些内容,您可以尝试使用多种编码对其进行解码,并查看缺少哪些。一般来说,没有办法,因为文本文件是文本文件,而这些文件很愚蠢;) EDIT:chardet似乎没有标记,但大部分答案都适用。检查是否有替代方

我收到一些经过编码的文本,但我不知道使用了什么字符集。有没有一种方法可以使用Python确定文本文件的编码?处理C#。

在一般情况下,原则上不可能确定文本文件的编码。因此,没有标准的Python库可以为您做到这一点


如果您对文本文件有更具体的了解(例如,它是XML),则可能有库函数。

如果您知道文件的某些内容,您可以尝试使用多种编码对其进行解码,并查看缺少哪些。一般来说,没有办法,因为文本文件是文本文件,而这些文件很愚蠢;)

EDIT:chardet似乎没有标记,但大部分答案都适用。检查是否有替代方案

始终正确检测编码是不可能的

(摘自chardet常见问题解答:)

但是,有些编码是优化的 对于特定语言,以及 它们不是随机的。某个人物 序列总是弹出,而 其他序列没有意义。A. 英语流利的人,开一家公司 报纸和发现“txzqJv 2!dasd0a QqdKjvz“将立即意识到这一点 那不是英语(尽管是) 完全由英文字母组成)。 通过研究大量的“典型”文本 计算机算法可以模拟这种情况 有点流利,做一个受过教育的人 猜测文本的语言

有一个图书馆利用这项研究来检测编码。chardet是Mozilla中自动检测代码的一个端口

您也可以使用。它将尝试以下方法:

  • 在文档本身中发现的编码:例如,在XML声明或(对于HTML文档)http等价元标记中。如果Beautiful Soup在文档中找到这种编码,它会从一开始就再次解析文档,并尝试使用新的编码。唯一的例外是,如果您显式指定了一种编码,并且该编码确实有效:那么它将忽略在文档中找到的任何编码
  • 通过查看文件的前几个字节嗅探到的编码。如果在此阶段检测到编码,它将是UTF-*编码、EBCDIC或ASCII之一
  • 库嗅探到的编码(如果已安装)
  • UTF-8
  • Windows-1252

一些编码策略,请取消注释以品尝:

#!/bin/bash
#
tmpfile=$1
echo '-- info about file file ........'
file -i $tmpfile
enca -g $tmpfile
echo 'recoding ........'
#iconv -f iso-8859-2 -t utf-8 back_test.xml > $tmpfile
#enca -x utf-8 $tmpfile
#enca -g $tmpfile
recode CP1250..UTF-8 $tmpfile
您可能希望通过以循环的形式打开并读取文件来检查编码。。。但您可能需要先检查文件大小:

#PYTHON
encodings = ['utf-8', 'windows-1250', 'windows-1252'] # add more
            for e in encodings:
                try:
                    fh = codecs.open('file.txt', 'r', encoding=e)
                    fh.readlines()
                    fh.seek(0)
                except UnicodeDecodeError:
                    print('got unicode error with %s , trying different encoding' % e)
                else:
                    print('opening the file with encoding:  %s ' % e)
                    break              

计算编码的另一个选项是使用 (哪一个是密码 命令)。有大量的 python绑定可用

位于文件源代码树中的python绑定可用作 (或) debian软件包。它可以通过执行以下操作来确定文件的编码:

导入魔法
blob=open('unknown-file','rb')。read()
m=magic.open(magic.magic\u MIME\u编码)
m、 加载()
编码=m.buffer(blob)#“utf-8”“us ascii”等
pypi上有一个名称相同但不兼容的pip包,它也使用
libmagic
。它还可以通过执行以下操作获得编码:

导入魔法
blob=open('unknown-file','rb')。read()
m=magic.magic(mime\u编码=True)
编码=来自缓冲区(blob)的m

根据您的平台,我只选择使用linux shell
文件
命令。这对我来说很有用,因为我在一个脚本中使用它,这个脚本只在我们的一台linux机器上运行

显然,这不是一个理想的解决方案或答案,但它可以根据您的需要进行修改。在我的例子中,我只需要确定一个文件是否为UTF-8

import subprocess
file_cmd = ['file', 'test.txt']
p = subprocess.Popen(file_cmd, stdout=subprocess.PIPE)
cmd_output = p.stdout.readlines()
# x will begin with the file type output as is observed using 'file' command
x = cmd_output[0].split(": ")[1]
return x.startswith('UTF-8')

下面是一个读取和获取面值a
chardet
编码预测的示例,如果文件较大,则从文件中读取
n行

chardet
还提供了它的编码预测的概率(即
置信度
)(还没有查看它们是如何得出的),它与它的预测一起从
chardet.predict()
返回,因此如果您愿意,您可以以某种方式使用它

def predict_encoding(file_path, n_lines=20):
    '''Predict a file's encoding using chardet'''
    import chardet

    # Open the file as binary data
    with open(file_path, 'rb') as f:
        # Join binary lines for specified number of lines
        rawdata = b''.join([f.readline() for _ in range(n_lines)])

    return chardet.detect(rawdata)['encoding']

此站点有用于识别ascii、使用bom编码和utf8无bom的python代码:。将文件读入字节数组(数据):。这里有一个例子。我在osx

#!/usr/bin/python                                                                                                  

import sys

def isUTF8(data):
    try:
        decoded = data.decode('UTF-8')
    except UnicodeDecodeError:
        return False
    else:
        for ch in decoded:
            if 0xD800 <= ord(ch) <= 0xDFFF:
                return False
        return True

def get_bytes_from_file(filename):
    return open(filename, "rb").read()

filename = sys.argv[1]
data = get_bytes_from_file(filename)
result = isUTF8(data)
print(result)


PS /Users/js> ./isutf8.py hi.txt                                                                                     
True
#/usr/bin/python
导入系统
def isUTF8(数据):
尝试:
解码=数据。解码('UTF-8')
除UNICEDECODEERROR外:
返回错误
其他:
对于已解码的信道:

如果0xD800这可能会有帮助

from bs4 import UnicodeDammit
with open('automate_data/billboard.csv', 'rb') as file:
   content = file.read()

suggestion = UnicodeDammit(content)
suggestion.original_encoding
#'iso-8859-1'

使用linux
file-i
命令

import subprocess

file = "path/to/file/file.txt"

encoding =  subprocess.Popen("file -bi "+file, shell=True, stdout=subprocess.PIPE).stdout

encoding = re.sub(r"(\\n)[^a-z0-9\-]", "", str(encoding.read()).split("=")[1], flags=re.IGNORECASE)
    
print(encoding)

您可以使用` python magic package,它不会将整个文件加载到内存中:

导入魔法
def检测(
文件路径,
):
回归魔法,魔法(
mime_encoding=True,
).from_文件(文件路径)
输出是编码名称,例如:

  • iso-8859-1
  • 美国ascii码
  • utf-8

感谢您的
chardet
参考资料。看起来不错,虽然有点慢。@rillo:没有所谓的“编码标准”。文本编码和计算机一样古老,它是随着时间和需求而有机地发展起来的,这是没有计划的。“Unicode”试图解决这个问题。从各方面考虑,这并不是一个坏主意。我想知道的是,我如何找出打开的文本文件是用什么编码的?@邓布利多我说的是,一直正确地检测它是不可能的。你所能做的只是猜测,但有时它可能会失败,它不会每次都起作用,因为编码不是真正可检测的。要进行猜测,您可以使用我在回答中建议的工具之一显然
cchardet
更快,但需要
cython
libmagic
确实是
chardet
的可行替代品。关于名为
pythonmagic
的独特软件包的详细信息!我是
import subprocess

file = "path/to/file/file.txt"

encoding =  subprocess.Popen("file -bi "+file, shell=True, stdout=subprocess.PIPE).stdout

encoding = re.sub(r"(\\n)[^a-z0-9\-]", "", str(encoding.read()).split("=")[1], flags=re.IGNORECASE)
    
print(encoding)