我需要将一些文件转换为UTF-8,因为它们是在UTF-8网站上输出的,而且有时内容看起来有点难看。
我现在可以做到这一点,或者我可以在阅读时做到这一点(通过PHP,只使用fopen,没什么特别的)。欢迎任何建议。
答案 0 :(得分:7)
我没有一个明确的PHP解决方案,但对于Python,我个人使用Universal Encoding Detector library,它在猜测文件的编码方式方面做得非常好。
为了让你开始,这是我用来进行转换的Python脚本(最初的目的是我想用UTF-16和Shift-JIS的混合物转换日语代码库,我做了如果chardet对检测编码没有信心则默认猜测:
import sys
import codecs
import chardet
from chardet.universaldetector import UniversalDetector
""" Detects encoding
Returns chardet result"""
def DetectEncoding(fileHdl):
detector = UniversalDetector()
for line in fileHdl:
detector.feed(line)
if detector.done: break
detector.close()
return detector.result
""" Reencode file to UTF-8
"""
def ReencodeFileToUtf8(fileName, encoding):
#TODO: This is dangerous ^^||, would need a backup option :)
#NOTE: Use 'replace' option which tolerates errorneous characters
data = codecs.open(fileName, 'rb', encoding, 'replace').read()
open(fileName, 'wb').write(data.encode('utf-8', 'replace'))
""" Main function
"""
if __name__=='__main__':
# Check for arguments first
if len(sys.argv) <> 2:
sys.exit("Invalid arguments supplied")
fileName = sys.argv[1]
try:
# Open file and detect encoding
fileHdl = open(fileName, 'rb')
encResult = DetectEncoding(fileHdl)
fileHdl.close()
# Was it an empty file?
if encResult['confidence'] == 0 and encResult['encoding'] == None:
sys.exit("Possible empty file")
# Only attempt to reencode file if we are confident about the
# encoding and if it's not UTF-8
encoding = encResult['encoding'].lower()
if encResult['confidence'] >= 0.7:
if encoding != 'utf-8':
ReencodeFileToUtf8(fileName, encoding)
else:
# TODO: Probably you could make a default guess and try to encode, or
# just simply make it fail
except IOError:
sys.exit('An IOError occured')
答案 1 :(得分:3)
只进行一次可以提高性能并减少未来出错的可能性,但如果您不知道编码,则根本无法进行正确的转换。
答案 2 :(得分:2)
我的第一次尝试是:
答案 3 :(得分:1)
文件是否可以包含来自不同代码页的数据?
如果是,则根本无法进行批量转换。您必须知道文件中每个子字符串的每个代码页。
如果没有,可以一次批量转换文件,但假设您知道该文件有哪些代码页。所以我们或多或少地回到了与上面相同的情况,我们只是将抽象从子字符串范围移到了文件范围。
所以,你需要问自己的问题是。您是否了解某些数据所属的代码页?如果没有,它仍然会显得很难看。
你总是可以对你的数据做一些分析并猜测代码页,虽然这可能会让它变得更加微不足道,但你仍然在猜测,因此它仍然会很难看:)