पायथन इंटरप्रेटर को सही तरीके से नॉन- ASCII कैरेक्टर को स्ट्रिंग ऑपरेशन में कैसे करें?


104

मेरे पास एक स्ट्रिंग है जो ऐसा दिखता है:

6 918 417 712

स्पष्ट कटौती तरीका यह स्ट्रिंग ट्रिम करने के लिए (के रूप में मैं समझता हूँ अजगर) बस कहने के लिए स्ट्रिंग एक चर बुलाया में है s, हम पाते हैं:

s.replace('Â ', '')

यह ट्रिक काम आना चाहिए। लेकिन निश्चित रूप से यह शिकायत करता है कि '\xc2'फ़ाइल blabla.py में गैर- ASCII वर्ण एन्कोडेड नहीं है।

मैं कभी नहीं समझ सका कि अलग-अलग एन्कोडिंग के बीच कैसे स्विच किया जाए।

यहां कोड है, यह वास्तव में ऊपर के समान ही है, लेकिन अब यह संदर्भ में है। फ़ाइल को नोटपैड में UTF-8 के रूप में सहेजा गया है और इसमें निम्नलिखित हेडर हैं:

#!/usr/bin/python2.4
# -*- coding: utf-8 -*-

कोड:

f = urllib.urlopen(url)

soup = BeautifulSoup(f)

s = soup.find('div', {'id':'main_count'})

#making a print 's' here goes well. it shows 6Â 918Â 417Â 712

s.replace('Â ','')

save_main_count(s)

इससे आगे नहीं मिलता है s.replace...


1
अब तक के सभी 4 जवाबों की कोशिश की। नही जाओ। अभी भी यूनिकोडडॉक्टररूट प्राप्त कर रहा है: 'एससीआई' कोडक 0x2 को बाइट नहीं कर सकता है 1 स्थिति में: ऑर्डिनल रेंज में नहीं है (128)
एड्रैगार्ड

आपके यूनिकोड स्ट्रिंग को प्रीपेंड किया जाना चाहिएu
SilentGhost

@SilentGhost: जैसा कि आप देख सकते हैं, यह सुनिश्चित करने का कोई तरीका नहीं है कि यह एक यूनिकोड स्ट्रिंग है। मुझे एक स्ट्रिंग मिलती है जिसमें ऊपर दी गई सामग्री होती है, लेकिन इसमें गैर एसिसीआई तार होते हैं। यही असली समस्या है। मुझे लगता है कि यह यूनिकोड है क्योंकि यह पहले 128 में नहीं है।
एडेरगार्ड

त्रुटि का आने वाली स्ट्रिंग से कोई लेना-देना नहीं है। यह आपके कोड में एक स्ट्रिंग है जो इस त्रुटि को उठाता है!
साइलेंटगॉस्ट

2
मैं शर्त लगा सकता हूं कि इस तरह के भ्रम से बचने के लिए, पायथन 3 स्ट्रिंग्स और बाइट अनुक्रमों के बीच के अंतर के बारे में इतना सख्त है।
मार्क रैनसम

जवाबों:


84

पायथन 2 asciiस्रोत फ़ाइलों के लिए डिफ़ॉल्ट एन्कोडिंग के रूप में उपयोग करता है , जिसका अर्थ है कि आपको शाब्दिक में गैर-एसिसी यूनिकोड वर्ण का उपयोग करने के लिए फ़ाइल के शीर्ष पर एक और एन्कोडिंग निर्दिष्ट करना होगा। पायथन 3 utf-8स्रोत फ़ाइलों के लिए डिफ़ॉल्ट एन्कोडिंग के रूप में उपयोग करता है , इसलिए यह एक समस्या से कम है।

देखें: http://docs.python.org/tutorial/interpreter.html#source-code-encoding

Utf-8 स्रोत एन्कोडिंग को सक्षम करने के लिए, यह शीर्ष दो लाइनों में से एक में जाएगा:

# -*- coding: utf-8 -*-

उपरोक्त डॉक्स में है, लेकिन यह भी काम करता है:

# coding: utf-8

अतिरिक्त मुद्दो पर विचार करना:

  • स्रोत फ़ाइल को आपके पाठ संपादक में सही एन्कोडिंग का उपयोग करके भी सहेजा जाना चाहिए।

  • पाइथन 2 में, यूनिकोड शाब्दिक के uपहले एक होना चाहिए , s.replace(u"Â ", u"")लेकिन इन पाइथन 3 में, बस उद्धरण का उपयोग करें। पायथन 2 में, आप from __future__ import unicode_literalsपायथन 3 व्यवहार को प्राप्त कर सकते हैं, लेकिन ध्यान रखें कि यह पूरे वर्तमान मॉड्यूल को प्रभावित करता है।

  • s.replace(u"Â ", u"")भी असफल हो जाएगा अगर sएक यूनिकोड स्ट्रिंग नहीं है।

  • string.replace एक नया स्ट्रिंग लौटाता है और जगह में संपादित नहीं करता है, इसलिए सुनिश्चित करें कि आप रिटर्न मान का भी उपयोग कर रहे हैं


4
आपको वास्तव में केवल जरूरत है # coding: utf-8-*-सजावट के लिए नहीं है, लेकिन आप कभी भी इसकी आवश्यकता की संभावना नहीं है। मुझे लगता है कि यह पुराने गोले के लिए था।
फेमिना

157
def removeNonAscii(s): return "".join(filter(lambda x: ord(x)<128, s))

संपादित करें: मेरा पहला आवेग हमेशा एक फिल्टर का उपयोग करने के लिए होता है, लेकिन जनरेटर की अभिव्यक्ति अधिक स्मृति कुशल (और छोटी) है ...

def removeNonAscii(s): return "".join(i for i in s if ord(i)<128)

ध्यान रखें कि यह UTF-8 एन्कोडिंग के साथ काम करने की गारंटी है (क्योंकि मल्टी-बाइट वर्णों में सभी बाइट्स 1 से सबसे अधिक सेट हैं)।


1
मुझे मिलता है: TypeError: ord () एक चरित्र की उम्मीद है, लेकिन लंबाई 2 की स्ट्रिंग मिली
Ivelin

@ इवेलिन ऐसा इसलिए है क्योंकि "चरित्र" को उचित यूनिकोड के रूप में व्याख्यायित नहीं किया जा रहा है ... जाँच करें कि आपके स्रोत स्ट्रिंग के साथ उपसर्ग है uअगर यह एक शाब्दिक है।
फोरट्रान

35
>>> unicode_string = u"hello aåbäcö"
>>> unicode_string.encode("ascii", "ignore")
'hello abc'

4
मुझे आपके द्वारा दिए गए वोट मिलते हैं, लेकिन जब मैं कोशिश करता हूं तो यह कहता है: नहीं। यूनिकोडडॉफॉर्सेट: ci एससीआई ’कोडक 1 स्थिति में बाइट 0xc2 को डिकोड नहीं कर सकता है: क्रमिक सीमा (128) में नहीं। क्या ऐसा हो सकता है कि मेरा ओरिजिनल स्ट्रिंग यूनिकोड में न हो? खैर किसी भी मामले में। इसकी आवश्यकता है
एडगरगार्ड

2
अच्छा धन्यवाद। क्या मैं मूल कोडिंग में इसे प्राप्त करने के लिए .decode () परिणाम पर उपयोग करने का सुझाव दूंगा?
अंकिरॉस

यदि आपको यूनिकोडडबलप्रोग्राम: 'एससीआई' मिल रहा है, तो एन्कोडिंग फ़ंक्शन को लागू करने से पहले स्ट्रिंग को '' यूटीएफ -8 'प्रारूप में बदलने का प्रयास करें।
सतीश

16

निम्नलिखित कोड सभी गैर ASCII वर्णों को प्रश्नवाचक चिन्ह से बदल देगा।

"".join([x if ord(x) < 128 else '?' for x in s])

जिज्ञासा से बाहर, मैं यह जानना चाहता था कि, क्या प्रश्न चिन्ह के साथ इसे बदलने का कोई विशेष कारण है?
मोहसिन

6

रेगेक्स का उपयोग करना:

import re

strip_unicode = re.compile("([^-_a-zA-Z0-9!@#%&=,/'\";:~`\$\^\*\(\)\+\[\]\.\{\}\|\?\<\>\\]+|[^\s]+)")
print strip_unicode.sub('', u'6Â 918Â 417Â 712')

5

एक उत्तर के लिए बहुत देर हो चुकी है, लेकिन मूल स्ट्रिंग UTF-8 में था और '\ xc2 \ xa0' NO-BREAK अंतरिक्ष के लिए UTF-8 है। बस मूल स्ट्रिंग को डीकोड के रूप में s.decode('utf-8')(\ xa0 एक स्थान के रूप में प्रदर्शित करता है जब विंडोज -1252 या लैटिन -1 के रूप में गलत तरीके से डिकोड किया जाता है:

उदाहरण (पायथन 3)

s = b'6\xc2\xa0918\xc2\xa0417\xc2\xa0712'
print(s.decode('latin-1')) # incorrectly decoded
u = s.decode('utf8') # correctly decoded
print(u)
print(u.replace('\N{NO-BREAK SPACE}','_'))
print(u.replace('\xa0','-')) # \xa0 is Unicode for NO-BREAK SPACE

उत्पादन

6 918 417 712
6 918 417 712
6_918_417_712
6-918-417-712

3
#!/usr/bin/env python
# -*- coding: utf-8 -*-

s = u"6Â 918Â 417Â 712"
s = s.replace(u"Â", "") 
print s

यह प्रिंट आउट लेगा 6 918 417 712


नहीं। यूनिकोडडॉफॉर्सेट: ci एससीआई ’कोडक 1 स्थिति में बाइट 0xc2 को डिकोड नहीं कर सकता है: क्रमिक सीमा (128) में नहीं। क्या ऐसा हो सकता है कि मेरा ओरिजिनल स्ट्रिंग यूनिकोड में न हो? खैर किसी भी मामले में। मैं शायद कुछ गलत कर रहा हूं।
एडगार्ड

@adergaard, क्या आपने स्रोत फ़ाइल के शीर्ष पर # - - कोडिंग: utf-8 - - जोड़ा है ?
नादिया अल्रामली

हां, इस पृष्ठ के शीर्ष पर फिर से देखें, मैंने खोज को संपादित किया है और कोड और हेडर टिप्पणियों में डाल दिया है। आपकी सहायता के लिए धन्यवाद।
एडगरगार्ड

मुझे लगता है कि आपको यह पता लगाना होगा कि यूनिकोड में html या xml दस्तावेज़ से तार कैसे प्राप्त करें। उस पर अधिक जानकारी यहाँ: diveintopython.org/xml_processing/unicode.html
यशायाह

2

मुझे पता है कि यह एक पुराना धागा है, लेकिन मैंने अनुवाद विधि का उल्लेख करने के लिए मजबूर महसूस किया, जो हमेशा 128 (या यदि आवश्यक हो तो) के ऊपर सभी वर्ण कोड को बदलने का एक अच्छा तरीका है।

उपयोग : str। अनुवाद ( तालिका [, डिलीटचर्स] )

>>> trans_table = ''.join( [chr(i) for i in range(128)] + [' '] * 128 )

>>> 'Résultat'.translate(trans_table)
'R sultat'
>>> '6Â 918Â 417Â 712'.translate(trans_table)
'6  918  417  712'

पायथन 2.6 के साथ शुरू करके , आप किसी को भी तालिका सेट नहीं कर सकते हैं, और डिलीटचैर्स का उपयोग उन पात्रों को हटाने के लिए कर सकते हैं जो आप नहीं चाहते हैं जो कि मानक डॉक्स में http://docs.python.org/library/stdtypes पर दिखाए गए उदाहरणों में दिखाए गए हैं । एचटीएमएल

यूनिकोड स्ट्रिंग्स के साथ, अनुवाद तालिका 256-वर्ण स्ट्रिंग नहीं है, लेकिन कुंजी के रूप में प्रासंगिक वर्णों के ऑर्ड () के साथ एक तानाशाही है। लेकिन वैसे भी एक यूनिकोड स्ट्रिंग से एक उचित एससीआई स्ट्रिंग प्राप्त करना काफी सरल है, ऊपर वर्णित ट्रुप्पो द्वारा वर्णित विधि का उपयोग करके, अर्थात्: यूनिकोड_स्ट्रिंग.केनकोड ("एस्की", "अनदेखा")

सारांश के रूप में, यदि किसी कारण से आपको अस्सी स्ट्रिंग प्राप्त करने की आवश्यकता है (उदाहरण के लिए, जब आप एक मानक अपवाद उठाते हैं raise Exception, ascii_message), तो आप निम्न फ़ंक्शन का उपयोग कर सकते हैं:

trans_table = ''.join( [chr(i) for i in range(128)] + ['?'] * 128 )
def ascii(s):
    if isinstance(s, unicode):
        return s.encode('ascii', 'replace')
    else:
        return s.translate(trans_table)

अनुवाद के साथ अच्छी बात यह है कि आप वास्तव में उच्चारण वाले चरित्रों को प्रासंगिक गैर-उच्चारण किए गए ascii वर्णों में परिवर्तित कर सकते हैं बजाय इसके कि उन्हें हटाए या '?' द्वारा प्रतिस्थापित करें। यह अक्सर उपयोगी होता है, उदाहरण के लिए अनुक्रमण प्रयोजनों के लिए।


मुझे मिलता है: TypeError: चरित्र मानचित्रण पूर्णांक, कोई भी या यूनिकोड
Ivelin

1
s.replace(u'Â ', '')              # u before string is important

और अपनी .pyफाइल को यूनिकोड बनाएं ।


1

यह एक गंदा हैक है, लेकिन यह काम कर सकता है।

s2 = ""
for i in s:
    if ord(i) < 128:
        s2 += i

0

इसके लायक क्या था, मेरा चरित्र सेट था utf-8और मैंने क्लासिक " # -*- coding: utf-8 -*-" लाइन को शामिल किया था।

हालाँकि, मुझे पता चला कि किसी वेबपेज से इस डेटा को पढ़ते समय मेरे पास यूनिवर्सल न्यूलाइन्स नहीं थे।

मेरे पाठ में दो शब्द थे, " \r\n" द्वारा अलग । मैं केवल पर विभाजित कर रहा था \nऔर की जगह "\n"

एक बार जब मैंने लूप किया और चरित्र को प्रश्न में सेट देखा, तो मुझे गलती का एहसास हुआ।

तो, यह ASCII वर्ण सेट के भीतर भी हो सकता है , लेकिन एक ऐसा चरित्र जिसकी आपको उम्मीद नहीं थी।

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