Python dizesinde u '\ ufeff'


153

Aşağıdaki pıtırtı ile ilgili bir hata alıyorum:

UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 155: ordinal not in range(128)

Ne olduğundan emin u'\ufeff'değilim, web kazıma yaptığımda ortaya çıkıyor. Durumu nasıl düzeltebilirim? .replace()Dize yöntemi onun üzerinde çalışmaz.


6
Bu girdi nereden geliyor? Ne yapmaya çalışıyorsun? Lütfen Python kodunuzu ekleyin.

7
Bu arada, unicode göstergesini hatırlarsam .replace () işlevinin modern python'da çalıştığını görüyorum: s.replace (u '\ ufeff', '')
Doug Bradshaw

@DougBradshaw "modern python" derken, 2.7+ mi 3.0+ mı demek istediniz?
teewuane

İyi bir nokta. Anlamı, 2.7+.
Doug Bradshaw

Yanıtlar:


184

Unicode karakteri U+FEFFbayt sırası işareti veya BOM'dir ve büyük ve küçük endian UTF-16 kodlaması arasındaki farkı anlatmak için kullanılır. Web sayfasını doğru kodek kullanarak çözerseniz, Python sizin için kaldırır. Örnekler:

#!python2
#coding: utf8
u = u'ABC'
e8 = u.encode('utf-8')        # encode without BOM
e8s = u.encode('utf-8-sig')   # encode with BOM
e16 = u.encode('utf-16')      # encode with BOM
e16le = u.encode('utf-16le')  # encode without BOM
e16be = u.encode('utf-16be')  # encode without BOM
print 'utf-8     %r' % e8
print 'utf-8-sig %r' % e8s
print 'utf-16    %r' % e16
print 'utf-16le  %r' % e16le
print 'utf-16be  %r' % e16be
print
print 'utf-8  w/ BOM decoded with utf-8     %r' % e8s.decode('utf-8')
print 'utf-8  w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig')
print 'utf-16 w/ BOM decoded with utf-16    %r' % e16.decode('utf-16')
print 'utf-16 w/ BOM decoded with utf-16le  %r' % e16.decode('utf-16le')

Bunun EF BB BFUTF-8 kodlu bir Malzeme Listesi olduğuna dikkat edin . UTF-8 için gerekli değildir, sadece imza olarak işlev görür (genellikle Windows'ta).

Çıktı:

utf-8     'ABC'
utf-8-sig '\xef\xbb\xbfABC'
utf-16    '\xff\xfeA\x00B\x00C\x00'    # Adds BOM and encodes using native processor endian-ness.
utf-16le  'A\x00B\x00C\x00'
utf-16be  '\x00A\x00B\x00C'

utf-8  w/ BOM decoded with utf-8     u'\ufeffABC'    # doesn't remove BOM if present.
utf-8  w/ BOM decoded with utf-8-sig u'ABC'          # removes BOM if present.
utf-16 w/ BOM decoded with utf-16    u'ABC'          # *requires* BOM to be present.
utf-16 w/ BOM decoded with utf-16le  u'\ufeffABC'    # doesn't remove BOM if present.

O Not utf-16codec'i gerektirir BOM mevcut olması veya veri lüx veya little-endian ise Python bilmez.


201

Python 3'te bununla karşılaştım ve bu soruyu (ve çözümü ) buldum . Bir dosyayı açarken, Python 3 kodlamayı otomatik olarak işlemek için kodlama anahtar sözcüğünü destekler.

Bu olmadan, Malzeme Listesi okuma sonucuna dahil edilir:

>>> f = open('file', mode='r')
>>> f.read()
'\ufefftest'

Doğru kodlamayı vererek, BOM sonuçta atlanır:

>>> f = open('file', mode='r', encoding='utf-8-sig')
>>> f.read()
'test'

Sadece 2 sentim.


13
Teşekkür ederim, bu gerçek çözümdür ve kabul edilen cevap olmalıdır. Bu , ipin neden orada olduğu konusunda büyük bir fikir olsa da, buraya gelen insanların çoğu basit bir çözüm arıyor ve bu kadar.
neurino

3
Excel'den kaydedilmiş bir csv dosyasını okuma csv DictReader ile aynı sorunu vardı.
LArntz

1
Evet, Excel (Excel tarafından üretilen "csv" bile) gerçekten sıcak bir karmaşa.
osprey

4

Bu karakter Malzeme Listesi veya "Bayt Sırası İşareti" dir. Genellikle bir dosyanın ilk birkaç baytı olarak alınır ve verilerin geri kalanının kodlamasını nasıl yorumlayacağınızı anlatır. Devam etmek için karakteri kaldırabilirsiniz. Her ne kadar, hata 'ascii'ye dönüştürmeye çalıştığınızı söylediğinden, muhtemelen yapmaya çalıştığınız şey için başka bir kodlama seçmelisiniz.


4

Kazıdığınız içerik, ascii metni yerine unicode olarak kodlanır ve ascii'ye dönüşmeyen bir karakter elde edersiniz. Doğru 'çeviri' orijinal web sayfasının ne düşündüğüne bağlıdır. Python'un unicode sayfası , nasıl çalıştığına dair arka plan sağlar.

Sonucu yazdırmaya veya bir dosyaya yapıştırmaya mı çalışıyorsunuz? Hata o oluyor anlaşılacağı yazma okumuyor, soruna neden verileri. Bu soru , düzeltmeleri aramak için iyi bir yerdir.


0

İşte Mark Tolonen'in cevabına dayanıyor. Dize, 'test' kelimesinin '|' ile ayrılmış farklı dilleri içeriyordu, böylece farkı görebilirsiniz.

u = u'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
e8 = u.encode('utf-8')        # encode without BOM
e8s = u.encode('utf-8-sig')   # encode with BOM
e16 = u.encode('utf-16')      # encode with BOM
e16le = u.encode('utf-16le')  # encode without BOM
e16be = u.encode('utf-16be')  # encode without BOM
print('utf-8     %r' % e8)
print('utf-8-sig %r' % e8s)
print('utf-16    %r' % e16)
print('utf-16le  %r' % e16le)
print('utf-16be  %r' % e16be)
print()
print('utf-8  w/ BOM decoded with utf-8     %r' % e8s.decode('utf-8'))
print('utf-8  w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig'))
print('utf-16 w/ BOM decoded with utf-16    %r' % e16.decode('utf-16'))
print('utf-16 w/ BOM decoded with utf-16le  %r' % e16.decode('utf-16le'))

İşte bir test çalıştırması:

>>> u = u'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> e8 = u.encode('utf-8')        # encode without BOM
>>> e8s = u.encode('utf-8-sig')   # encode with BOM
>>> e16 = u.encode('utf-16')      # encode with BOM
>>> e16le = u.encode('utf-16le')  # encode without BOM
>>> e16be = u.encode('utf-16be')  # encode without BOM
>>> print('utf-8     %r' % e8)
utf-8     b'ABCtest\xce\xb2\xe8\xb2\x9d\xe5\xa1\x94\xec\x9c\x84m\xc3\xa1sb\xc3\xaata|test|\xd8\xa7\xd8\xae\xd8\xaa\xd8\xa8\xd8\xa7\xd8\xb1|\xe6\xb5\x8b\xe8\xaf\x95|\xe6\xb8\xac\xe8\xa9\xa6|\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88|\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa5\x80\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb7\xe0\xa4\xbe|\xe0\xb4\xaa\xe0\xb4\xb0\xe0\xb4\xbf\xe0\xb4\xb6\xe0\xb5\x8b\xe0\xb4\xa7\xe0\xb4\xa8|\xd7\xa4\xd6\xbc\xd7\xa8\xd7\x95\xd7\x91\xd7\x99\xd7\xa8\xd7\x9f|ki\xe1\xbb\x83m tra|\xc3\x96l\xc3\xa7ek|'
>>> print('utf-8-sig %r' % e8s)
utf-8-sig b'\xef\xbb\xbfABCtest\xce\xb2\xe8\xb2\x9d\xe5\xa1\x94\xec\x9c\x84m\xc3\xa1sb\xc3\xaata|test|\xd8\xa7\xd8\xae\xd8\xaa\xd8\xa8\xd8\xa7\xd8\xb1|\xe6\xb5\x8b\xe8\xaf\x95|\xe6\xb8\xac\xe8\xa9\xa6|\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88|\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa5\x80\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb7\xe0\xa4\xbe|\xe0\xb4\xaa\xe0\xb4\xb0\xe0\xb4\xbf\xe0\xb4\xb6\xe0\xb5\x8b\xe0\xb4\xa7\xe0\xb4\xa8|\xd7\xa4\xd6\xbc\xd7\xa8\xd7\x95\xd7\x91\xd7\x99\xd7\xa8\xd7\x9f|ki\xe1\xbb\x83m tra|\xc3\x96l\xc3\xa7ek|'
>>> print('utf-16    %r' % e16)
utf-16    b"\xff\xfeA\x00B\x00C\x00t\x00e\x00s\x00t\x00\xb2\x03\x9d\x8cTX\x04\xc7m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x00'\x06.\x06*\x06(\x06'\x061\x06|\x00Km\xd5\x8b|\x00,nf\x8a|\x00\xc60\xb90\xc80|\x00*\t0\t@\t\x15\tM\t7\t>\t|\x00*\r0\r?\r6\rK\r'\r(\r|\x00\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x05|\x00k\x00i\x00\xc3\x1em\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|\x00"
>>> print('utf-16le  %r' % e16le)
utf-16le  b"A\x00B\x00C\x00t\x00e\x00s\x00t\x00\xb2\x03\x9d\x8cTX\x04\xc7m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x00'\x06.\x06*\x06(\x06'\x061\x06|\x00Km\xd5\x8b|\x00,nf\x8a|\x00\xc60\xb90\xc80|\x00*\t0\t@\t\x15\tM\t7\t>\t|\x00*\r0\r?\r6\rK\r'\r(\r|\x00\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x05|\x00k\x00i\x00\xc3\x1em\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|\x00"
>>> print('utf-16be  %r' % e16be)
utf-16be  b"\x00A\x00B\x00C\x00t\x00e\x00s\x00t\x03\xb2\x8c\x9dXT\xc7\x04\x00m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x06'\x06.\x06*\x06(\x06'\x061\x00|mK\x8b\xd5\x00|n,\x8af\x00|0\xc60\xb90\xc8\x00|\t*\t0\t@\t\x15\tM\t7\t>\x00|\r*\r0\r?\r6\rK\r'\r(\x00|\x05\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x00|\x00k\x00i\x1e\xc3\x00m\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|"
>>> print()

>>> print('utf-8  w/ BOM decoded with utf-8     %r' % e8s.decode('utf-8'))
utf-8  w/ BOM decoded with utf-8     '\ufeffABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-8  w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig'))
utf-8  w/ BOM decoded with utf-8-sig 'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-16 w/ BOM decoded with utf-16    %r' % e16.decode('utf-16'))
utf-16 w/ BOM decoded with utf-16    'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-16 w/ BOM decoded with utf-16le  %r' % e16.decode('utf-16le'))
utf-16 w/ BOM decoded with utf-16le  '\ufeffABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'

It yetmeyecek yalnızca her iki olduğunu bilmek utf-8-sigve utf-16hem sonra orijinal dize geri almak encodeve decode.


-3

Bu sorun temel olarak python kodunuzu UTF-8 veya UTF-16 kodlamasına kaydettiğinizde ortaya çıkar çünkü python kodun başlangıcına otomatik olarak (metin editörleri tarafından gösterilmez) bazı özel karakterleri kodlama biçimini belirlemek için ekler. Ancak, kodu yürütmeye çalıştığınızda, satır 1'de sözdizimi hatası verir, yani kod başlangıcı, çünkü python derleyicisi ASCII kodlamasını anlar . read () işlevini kullanarak dosya kodunu görüntülediğinizde, döndürülen kodun başlangıcında görebileceğiniz '\ ufeff' gösterilir. Bu sorunun en basit çözümü sadece kodlamayı ASCII kodlamasına geri döndürmektir(bunun için kodunuzu bir not defterine kopyalayıp kaydedebilirsiniz Unutmayın! ASCII kodlamasını seçin ... Umarım bu yardımcı olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.