पायथन स्ट्रिंग में यू '\ ufeff'


153

मुझे निम्नलिखित संरक्षक के साथ एक त्रुटि मिलती है:

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

यकीन नहीं है कि क्या u'\ufeff'है, यह दिखाता है कि मैं वेब स्क्रैपिंग कब कर रहा हूं। मैं स्थिति को कैसे माप सकता हूं? .replace()स्ट्रिंग विधि इस पर काम नहीं करती है।


6
यह इनपुट कहां से आया है? आप क्या करने की कोशिश कर रहे हैं? कृपया अपना पायथन कोड शामिल करें।

7
संयोग से, मुझे लगता है कि .replace () आधुनिक अजगर में काम करता है अगर मुझे यूनिकोड संकेतक याद है: s.replace (u '\ ufeff', '')
डग ब्रैडशॉ

@DougBradshaw जब आप "आधुनिक अजगर" कहते हैं, तो क्या आपका मतलब 2.7+ या 3.0+ है?
तेयुएन

अच्छी बात। मतलब, 2.7+।
डग ब्रैडशॉ

जवाबों:


184

यूनिकोड चरित्र U+FEFFबाइट ऑर्डर मार्क या बीओएम है, और इसका उपयोग बड़े और छोटे-एंडियन यूटीएफ -16 एन्कोडिंग के बीच अंतर बताने के लिए किया जाता है। यदि आप सही कोडेक का उपयोग करके वेब पेज को डीकोड करते हैं, तो पायथन आपके लिए इसे हटा देगा। उदाहरण:

#!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')

ध्यान दें कि EF BB BFUTF-8-Encoded BOM है। यह UTF-8 के लिए आवश्यक नहीं है, लेकिन केवल एक हस्ताक्षर के रूप में कार्य करता है (आमतौर पर विंडोज पर)।

आउटपुट:

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.

ध्यान दें कि utf-16कोडेक को BOM मौजूद होने की आवश्यकता है , या पायथन को पता नहीं होगा कि डेटा बड़ा है या छोटा-सा एंडियन।


201

मैं पायथन 3 पर इस में भाग गया और यह प्रश्न (और समाधान पाया ) । फ़ाइल खोलते समय, पायथन 3 एन्कोडिंग को स्वचालित रूप से संभालने के लिए एन्कोडिंग कीवर्ड का समर्थन करता है।

इसके बिना, BOM को पढ़ने के परिणाम में शामिल किया गया है:

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

सही एन्कोडिंग देते हुए, BOM परिणाम में छोड़ा गया है:

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

बस मेरे 2 सेंट।


13
धन्यवाद, यह वास्तविक समाधान है और स्वीकृत उत्तर होना चाहिए। हालांकि यह इस बात की बहुत जानकारी है कि स्ट्रिंग क्यों है, यहां आने वाले अधिकांश लोग एक सीधा समाधान ढूंढ रहे हैं और यह वह है।
न्यूरिनो

3
एक्सेल से सहेजी गई एक सीएसवी फ़ाइल को पढ़ने वाले सीएसवी डिक्ट्रीडर के साथ भी यही मुद्दा था।
लॉरेंट्ज़

1
हाँ, एक्सेल (एक्सेल द्वारा उत्पन्न "सीएसवी") वास्तव में एक गर्म गड़बड़ है।
ओस्प्रे

4

वह पात्र BOM या "बाइट ऑर्डर मार्क" है। यह आमतौर पर एक फ़ाइल के पहले कुछ बाइट्स के रूप में प्राप्त होता है, आपको बताता है कि बाकी डेटा के एन्कोडिंग की व्याख्या कैसे करें। आप बस चरित्र को जारी रखने के लिए निकाल सकते हैं। हालाँकि, चूंकि त्रुटि कहती है कि आप 'एससीआई' में परिवर्तित होने की कोशिश कर रहे थे, इसलिए आपको जो भी करने की कोशिश कर रहे थे, उसके लिए आपको शायद एक और एन्कोडिंग चुननी चाहिए।


4

जिस सामग्री को आप स्क्रैप कर रहे हैं, वह यूसीआई पाठ के बजाय यूनिकोड में एन्कोडेड है, और आपको एक ऐसा चरित्र मिल रहा है जो एससीआई में परिवर्तित नहीं होता है। सही 'अनुवाद' इस बात पर निर्भर करता है कि मूल वेब पेज क्या सोचा था। पायथन का यूनिकोड पृष्ठ इस बात की पृष्ठभूमि देता है कि यह कैसे काम करता है।

क्या आप परिणाम को प्रिंट करने की कोशिश कर रहे हैं या इसे एक फ़ाइल में चिपका सकते हैं? त्रुटि बताती है कि यह उस डेटा को लिख रहा है जो समस्या का कारण है, इसे पढ़ना नहीं। यह प्रश्न फ़िक्सेस को देखने के लिए एक अच्छी जगह है।


0

यहाँ मार्क टॉलेनन के उत्तर पर आधारित है। स्ट्रिंग में 'टेस्ट' शब्द की अलग-अलग भाषाएं शामिल हैं जो '|' से अलग है, इसलिए आप अंतर देख सकते हैं।

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'))

यहाँ एक परीक्षण चलाया गया है:

>>> 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|'

यह जानने योग्य है कि केवल दोनों utf-8-sigऔर utf-16मूल स्ट्रिंग को दोनों के बाद वापस प्राप्त करें encodeऔर decode


-3

यह समस्या मूल रूप से तब उत्पन्न होती है जब आप अपने python कोड को UTF-8 या UTF-16 एन्कोडिंग में सहेजते हैं, क्योंकि एन्कोडिंग प्रारूप की पहचान करने के लिए अजगर स्वचालित रूप से कोड की शुरुआत में कुछ विशेष वर्ण जोड़ता है (जो कि पाठ संपादकों द्वारा नहीं दिखाया गया है)। लेकिन, जब आप कोड को निष्पादित करने का प्रयास करते हैं तो यह आपको लाइन 1 में वाक्यविन्यास त्रुटि देता है, अर्थात कोड की शुरुआत क्योंकि पायथन कंपाइलर ASCII एन्कोडिंग को समझता है । जब आप रीड () फ़ंक्शन का उपयोग करके फ़ाइल का कोड देखते हैं तो आप लौटे कोड की शुरुआत में देख सकते हैं '\ ufeff' दिखाया गया है। इस समस्या का सबसे सरल समाधान सिर्फ एन्कोडिंग को ASCII एन्कोडिंग में बदलना है(इसके लिए आप अपने कोड को एक नोटपैड पर कॉपी कर सकते हैं और इसे सेव कर सकते हैं। याद रखें! ASCII एनकोडिंग चुनें! आशा है कि यह मदद करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.