पायथन में फ़ाइल से वर्ण पढ़ने


102

एक पाठ फ़ाइल में, एक स्ट्रिंग है "मुझे यह पसंद नहीं है"।

हालाँकि, जब मैंने इसे एक स्ट्रिंग में पढ़ा, तो यह "I don \ xe2 \ x80 \ x98t इस तरह" हो गया। मैं समझता हूँ कि \ u2018 "" "का यूनिकोड प्रतिनिधित्व है। मैं उपयोग करता हूं

f1 = open (file1, "r")
text = f1.read()

रीडिंग करने की आज्ञा।

अब, क्या स्ट्रिंग को इस तरह से पढ़ना संभव है, जब इसे स्ट्रिंग में पढ़ा जाता है, तो "I don’t like this", "I don \ xe2 \ x80 \ x98t like this?"

दूसरा संपादन: मैंने कुछ लोगों को इस समस्या को हल करने के लिए मैपिंग का उपयोग करते देखा है, लेकिन क्या वास्तव में, कोई अंतर्निहित रूपांतरण नहीं है जो इस तरह के एएनएसआई को यूनिकोड (और इसके विपरीत) रूपांतरण के लिए करता है?


कुछ टिप्पणियां: मैंने देखा है कि कुछ लोग इस समस्या को हल करने के लिए मैपिंग का उपयोग करते हैं, लेकिन वास्तव में, क्या कोई अंतर्निहित रूपांतरण नहीं है जो इस तरह के एएनएसआई को यूनिकोड (और इसके विपरीत) रूपांतरण करता है? धन्यवाद!
ग्रेविटन

वहाँ नहीं है, क्योंकि यूनिकोड कोड बिंदुओं के सैकड़ों हजारों हैं। आप कैसे तय करेंगे कि एएससीआईआई के पात्रों को किस तरह मैप किया जाए?
जॉन मिलिकिन

2
btw, आपकी पाठ फ़ाइल टूट गई है! U + 2018 "LEFT SINGLE QUOTATION MARK" है, एपोस्ट्रोफ (U + 0027 आमतौर पर) नहीं।

जॉन, आपकी टिप्पणी गलत है, कम से कम सामान्य अर्थों में। iconv lib का उपयोग यूनिकोड वर्णों को ascii (यहां तक ​​कि स्थानीय निर्भर) $ python -c 'Print u "\ u2018" .encode ("utf-8") के लिए किया जा सकता है। 0000000: 270a

बात यह है, आपको UNICODE को ASCII में बदलने की आवश्यकता है (दूसरे तरीके से नहीं)।
hasen

जवाबों:


157

Ref: http://docs.python.org/howto/unicode

यूनिकोड को किसी फ़ाइल से पढ़ना इसलिए सरल है:

import codecs
with codecs.open('unicode.rst', encoding='utf-8') as f:
    for line in f:
        print repr(line)

अद्यतन मोड में फाइलें खोलना भी संभव है, जिससे पढ़ने और लिखने दोनों की अनुमति मिलती है:

with codecs.open('test', encoding='utf-8', mode='w+') as f:
    f.write(u'\u4500 blah blah blah\n')
    f.seek(0)
    print repr(f.readline()[:1])

संपादित करें : मैं मान रहा हूं कि आपका इच्छित लक्ष्य केवल पायथन में एक स्ट्रिंग में फ़ाइल को ठीक से पढ़ने में सक्षम होना है। यदि आप यूनिकोड से एक ASCII स्ट्रिंग को बदलने की कोशिश कर रहे हैं, तो ऐसा करने के लिए कोई सीधा रास्ता नहीं है, क्योंकि यूनिकोड वर्ण आवश्यक रूप से ASCII में मौजूद नहीं होंगे।

यदि आप ASCII स्ट्रिंग में बदलने की कोशिश कर रहे हैं, तो निम्न में से एक का प्रयास करें:

  1. ASCII समकक्षों के साथ विशिष्ट यूनिकोड वर्ण बदलें, यदि आप केवल कुछ विशेष मामलों को संभालना चाहते हैं जैसे कि इस विशेष उदाहरण

  2. unicodedataमॉड्यूल का उपयोग करें normalize()और string.encode()विधि को आप सबसे अच्छे रूप में अगले निकटतम ASCII समकक्ष (Ref https://web.archive.org/web/20090228203858/http://techxplorer.com/2006/07/18/converting- पर कनवर्ट कर सकते हैं) यूनिकोड-टू-एस्की-यूज़िंग-पायथन ):

    >>> teststr
    u'I don\xe2\x80\x98t like this'
    >>> unicodedata.normalize('NFKD', teststr).encode('ascii', 'ignore')
    'I donat like this'
    

3
codecsमॉड्यूल सार्वभौमिक newlines मोड को ठीक से नहीं संभालता है। io.open()अजगर 2.7+ के बजाय इसका उपयोग करें (यह open()पायथन 3 पर बनाया गया है)।
JFS

15

विचार करने के लिए कुछ बिंदु हैं।

एक \ u2018 चरित्र केवल पायथन में एक यूनिकोड स्ट्रिंग के प्रतिनिधित्व के टुकड़े के रूप में प्रकट हो सकता है, उदाहरण के लिए यदि आप लिखते हैं:

>>> text = u'‘'
>>> print repr(text)
u'\u2018'

अब यदि आप यूनिकोड स्ट्रिंग को पहले से प्रिंट करना चाहते हैं, तो यूनिकोड की encodeविधि का उपयोग करें:

>>> text = u'I don\u2018t like this'
>>> print text.encode('utf-8')
I dont like this

यह सुनिश्चित करने के लिए कि किसी भी फ़ाइल की प्रत्येक पंक्ति यूनिकोड के रूप में पढ़ी जाएगी, आप codecs.openकेवल इसके बजाय फ़ंक्शन का बेहतर उपयोग करेंगे open, जो आपको फ़ाइल की एन्कोडिंग निर्दिष्ट करने की अनुमति देता है:

>>> import codecs
>>> f1 = codecs.open(file1, "r", "utf-8")
>>> text = f1.read()
>>> print type(text)
<type 'unicode'>
>>> print text.encode('utf-8')
I dont like this

6

लेकिन यह वास्तव में "मैं इस तरह से \ u2018t नहीं" और "मुझे यह पसंद नहीं है"। चरित्र u '\ u2018' "" "की तुलना में एक पूरी तरह से अलग चरित्र है (और, नेत्रहीन, को '`' के अनुरूप होना चाहिए)।

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

punctuation = {
  u'\u2018': "'",
  u'\u2019': "'",
}
for src, dest in punctuation.iteritems():
  text = text.replace(src, dest)

यूनिकोड में विस्मयकारी पात्रों के एक बहुत सारे हैं , लेकिन मुझे लगता है कि आप उनमें से कुछ पर ही भरोसा कर सकते हैं कि जो भी एप्लिकेशन आपके द्वारा पढ़े जा रहे दस्तावेजों को बना रहा है।


1
वास्तव में, यदि आप यूनिकोड अध्यादेशों के लिए यूनिकोड अध्यादेश ({0x2018: 0x27, 0x2019: 0x27}) बनाते हैं, तो आप एक बार में सभी रिप्लेसमेंट करने के लिए पूरे ताना को text.translate () में पास कर सकते हैं।
थॉमस वाउचर

5

पायथन 3 रीड मेथड का उपयोग करके एन्कोडेड टेक्स्ट फाइल पढ़ना भी संभव है:

f = open (file.txt, 'r', encoding='utf-8')
text = f.read()
f.close()

इस भिन्नता के साथ, किसी भी अतिरिक्त पुस्तकालयों को आयात करने की आवश्यकता नहीं है


3

इस तथ्य को छोड़ते हुए कि आपकी पाठ फ़ाइल टूट गई है (U + 2018 एक बाएं उद्धरण चिह्न है, न कि एपॉस्ट्रॉफी): आइकनव का उपयोग यूनिकोड वर्णों को एसेसी में बदलने के लिए किया जा सकता है।

आपको "iconvcodec" के लिए Google करना होगा, क्योंकि मॉड्यूल अब समर्थित नहीं है और मुझे इसके लिए एक कैनोनिकल होम पेज नहीं मिल सकता है।

>>> import iconvcodec
>>> from locale import setlocale, LC_ALL
>>> setlocale(LC_ALL, '')
>>> u'\u2018'.encode('ascii//translit')
"'"

वैकल्पिक रूप से आप iconvअपनी फ़ाइल को साफ करने के लिए कमांड लाइन उपयोगिता का उपयोग कर सकते हैं :

$ xxd foo
0000000: e280 980a                                ....
$ iconv -t 'ascii//translit' foo | xxd
0000000: 270a                                     '.

2

एक संभावना है कि किसी तरह आपके पास यूनिकोड से बचने के लिए एक गैर-यूनिकोड स्ट्रिंग है, जैसे:

>>> print repr(text)
'I don\\u2018t like this'

यह वास्तव में मेरे साथ एक बार पहले हुआ था। आप unicode_escapeस्ट्रिंग को यूनिकोड में डिकोड करने के लिए एक कोडेक का उपयोग कर सकते हैं और फिर इसे किसी भी प्रारूप में एनकोड कर सकते हैं जिसे आप चाहते हैं:

>>> uni = text.decode('unicode_escape')
>>> print type(uni)
<type 'unicode'>
>>> print uni.encode('utf-8')
I dont like this

1

यह पायथन का तरीका है जो आपको यूनिकोड एनकोडेड स्ट्रिंग्स दिखाता है। लेकिन मुझे लगता है कि आपको स्क्रीन पर स्ट्रिंग को प्रिंट करने या किसी भी समस्या के बिना एक नई फ़ाइल में लिखने में सक्षम होना चाहिए।

>>> test = u"I don\u2018t like this"
>>> test
u'I don\u2018t like this'
>>> print test
I dont like this

1

दरअसल, U + 2018 विशेष चरित्र का यूनिकोड प्रतिनिधित्व है। ' यदि आप चाहें, तो आप इस कोड से उस वर्ण के उदाहरणों को U + 0027 में परिवर्तित कर सकते हैं:

text = text.replace (u"\u2018", "'")

इसके अलावा, आप फ़ाइल लिखने के लिए क्या उपयोग कर रहे हैं? f1.read()इस तरह दिखता है कि एक स्ट्रिंग लौटना चाहिए:

'I don\xe2\x80\x98t like this'

यदि यह इस स्ट्रिंग को लौटा रहा है, तो फ़ाइल गलत तरीके से लिखी जा रही है:

'I don\u2018t like this'

माफ़ करना! जैसा कि आपने कहा, यह 'I don \ xe2 \ x80 \ x98t इस तरह से लौट रहा है'
Graviton

'I don \ xe2 \ x80 \ x98t इस तरह से' कि आप देख रहे हैं कि पायथन क्या कहेगा। यह यू'आई डॉन \ u2018t की utf-8 एन्कोडिंग जैसा प्रतीत होता है ', जो कि पायथन में एक यूनिकोड उदाहरण है। पूर्व पर या .encode ('utf-8') पर .decode ('utf-8') कॉल करने का प्रयास करें।
लोगन

@ एचओपी: उफ़, भूल गए ऑर्ड () हेक्स के बजाय दशमलव लौटाता है। पकड़ने के लिए धन्यवाद।
जॉन मिलिकिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.