Chỉ cần sử dụng codec "UTF-8-SIG":
fp = open["file.txt"]
s = fp.read[]
u = s.decode["utf-8-sig"]
Điều đó cung cấp cho bạn một chuỗi unicode
mà không có BOM. Sau đó bạn có thể sử dụng
s = u.encode["utf-8"]
Để có được một chuỗi được mã hóa UTF-8 bình thường trở lại trong s
. Nếu các tập tin của bạn lớn, thì bạn nên tránh đọc tất cả vào bộ nhớ. BOM chỉ đơn giản là ba byte ở đầu tệp, vì vậy bạn có thể sử dụng mã này để loại bỏ chúng ra khỏi tệp:
import os, sys, codecs
BUFSIZE = 4096
BOMLEN = len[codecs.BOM_UTF8]
path = sys.argv[1]
with open[path, "r+b"] as fp:
chunk = fp.read[BUFSIZE]
if chunk.startswith[codecs.BOM_UTF8]:
i = 0
chunk = chunk[BOMLEN:]
while chunk:
fp.seek[i]
fp.write[chunk]
i += len[chunk]
fp.seek[BOMLEN, os.SEEK_CUR]
chunk = fp.read[BUFSIZE]
fp.seek[-BOMLEN, os.SEEK_CUR]
fp.truncate[]
Nó mở tệp, đọc một đoạn và viết nó vào tệp 3 byte sớm hơn so với nơi nó đọc nó. Các tập tin được viết lại tại chỗ. Vì giải pháp dễ dàng hơn là viết tệp ngắn hơn vào một tệp mới như câu trả lời của Newtover. Điều đó sẽ đơn giản hơn, nhưng sử dụng hai lần không gian đĩa trong một thời gian ngắn.
Đối với việc đoán mã hóa, sau đó bạn chỉ có thể lặp qua mã hóa từ hầu hết đến cụ thể nhất:
def decode[s]:
for encoding in "utf-8-sig", "utf-16":
try:
return s.decode[encoding]
except UnicodeDecodeError:
continue
return s.decode["latin-1"] # will always work
Một tệp được mã hóa UTF-16 sẽ không giải mã là UTF-8, vì vậy chúng tôi thử với UTF-8 trước. Nếu điều đó thất bại, thì chúng tôi sẽ thử với UTF-16. Cuối cùng, chúng tôi sử dụng Latin-1-điều này sẽ luôn hoạt động vì tất cả 256 byte là giá trị pháp lý trong Latin-1. Bạn có thể muốn trả lại None
thay vào đó trong trường hợp này vì nó thực sự là một dự phòng và mã của bạn có thể muốn xử lý điều này một cách cẩn thận hơn [nếu có thể].
Xin chào,
Tôi đã đọc một số văn bản từ tệp văn bản được mã hóa UTF-8 như thế này:
Text = codecs.open ['example.txt', 'r', 'utf8']. Đọc []
Nếu tôi chuyển văn bản này cho một đối tượng COM, tôi có thể thấy rằng vẫn còn BOM trong tệp, đánh dấu tệp là UTF-8. Chỉ cần xóa ký tự đầu tiên trong chuỗi là không ổn, vì BOM là tùy chọn. Vì vậy, tôi đã thử một cái gì đó như thế này:
in the file, which marks the file as utf-8. Simply removing the first
character in the string is not ok, because the BOM is optional. So I
tried
something like this:
if text.startswith [codecs.bom_utf8]: in "tìm thấy bom"
print "found BOM"
Nhưng sau đó tôi gặp lỗi sau:
UnicodedEcodeError: 'ASCII' codec không thể giải mã byte 0xef ở vị trí 0: Ordinal không trong phạm vi [128]
ordinal not in range[128]
Cách đúng để loại bỏ BOM khỏi chuỗi là gì?
Trân trọng, Achim
Achim
18 tháng 7 '05 #1
Bỏ qua nội dung
Khi làm việc với TensorFlow và Tflearn trên Windows, tôi thường gặp sự cố với các tệp dữ liệu nguồn của mình được mã hóa dưới dạng UTF-8 với tiêu đề BOM. & nbsp; một BOM là một dấu lệnh byte, một ký tự Unicode duy nhất có tính đến tệp. & nbsp; nhiều tiện ích tải dữ liệu với mã hóa không chính xác và sẽ ném Các tệp lớn thường được sử dụng làm dữ liệu đào tạo có thể là một thách thức để mở/mã lại đúng cách để tôi tạo phương thức này để viết lại tệp tại chỗ mà không có dấu BOM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Nhập hệ điều hành, sys, codecsos,sys,codecs def remove_bom_inplace [đường dẫn]:remove_bom_inplace[path]: & nbsp; & nbsp; & nbsp; & nbsp; "" "Xóa BOM Mark, nếu nó tồn tại, từ một tệp và viết lại nó tại chỗ" """""Removes BOM mark, if it exists, from a file and rewrites it in-place""" buffer_size=4096buffer_size
=4096 bom_length=len[codecs.BOM_UTF8]bom_length=len[codecs.BOM_UTF8] & nbsp;with open[path,"r+b"]asfp: chunk=fp.read[buffer_size]chunk=fp.read[buffer_size] ifchunk.startswith[codecs.BOM_UTF8]:ifchunk.startswith[codecs.BOM_UTF8]: i=0i
=0 chunk=chunk[bom_length:]chunk=chunk[bom_length:] whilechunk:whilechunk: fp.seek[i]fp.seek[i]
fp.write[chunk]fp.write[chunk] i+=len[chunk]i+=len[chunk] fp.seek[bom_length,os.SEEK_CUR]fp.seek[bom_length,
os.SEEK_CUR] chunk=fp.read[buffer_size]chunk=fp.read[buffer_size] fp.seek[-bom_length,os.SEEK_CUR]fp.seek[-bom_length,
os.SEEK_CUR] fp.truncate[]fp.truncate[]ValueError
về ký tự bất ngờ này.
Tôi thực sự sử dụng điều này trong các tập lệnh đào tạo Tflearn của mình, như thế này:
try:: data,labels=load_csv[...]data,labels=load_csv[...] ngoại trừ valueError:ValueError: strip_bom.remove_bom_inplace[filename]strip_bom.remove_bom_inplace[filename] data,labels=load_csv[...]data,labels=load_csv[...] |
Sao cho bất kỳ lỗi liên quan đến BOM nào trong quá trình tải cố gắng sửa chữa tệp và tự động thử lại.