কোনও পাঠ্য ফাইলে ইউনিকোড পাঠ্য লিখছেন?


225

আমি গুগল ডক থেকে ডেটা টানছি, এটি প্রক্রিয়া করছি এবং একটি ফাইলে লিখছি (এটি শেষ পর্যন্ত আমি ওয়ার্ডপ্রেস পৃষ্ঠাতে পেস্ট করব)।

এটিতে কিছু নন-এএসসিআইআই চিহ্ন রয়েছে। আমি কীভাবে এগুলি এইচটিএমএল উত্সে ব্যবহার করা যেতে পারে সেই চিহ্নগুলিতে নিরাপদে রূপান্তর করতে পারি?

বর্তমানে আমি সমস্ত কিছুর পথে ইউনিকোডে রূপান্তর করছি, একে একে পাইথন স্ট্রিংয়ে একসাথে যোগদান করছি, তারপরে:

import codecs
f = codecs.open('out.txt', mode="w", encoding="iso-8859-1")
f.write(all_html.encode("iso-8859-1", "replace"))

শেষ লাইনে একটি এনকোডিং ত্রুটি রয়েছে:

ইউনিকোড ডিকোড এরর: 'এসকিআই' কোডেক 12x6 পজিশনে 0xa0 বাইট ডিকোড করতে পারে না: সীমাবদ্ধ নয় (128)

আংশিক সমাধান:

এই পাইথনটি ত্রুটি ছাড়াই চলে:

row = [unicode(x.strip()) if x is not None else u'' for x in row]
all_html = row[0] + "<br/>" + row[1]
f = open('out.txt', 'w')
f.write(all_html.encode("utf-8"))

তবে আমি যদি প্রকৃত পাঠ্য ফাইলটি খুলি, তবে আমি প্রচুর প্রতীক দেখতে পাচ্ছি:

Qur’an 

টেক্সট ফাইল বাদে অন্য কিছু লিখতে হবে?


1
আপনি যে প্রোগ্রামটি এটি খোলার জন্য ব্যবহার করছেন তা ইউটিএফ -8 পাঠ্যের সঠিক ব্যাখ্যা দিচ্ছে না। এটিতে ইউটিএফ -8 হিসাবে ফাইলটি খোলার বিকল্প থাকা উচিত।
থমাস কে

উত্তর:


322

আপনি যখন প্রথমবার পাবেন তখন ইউনিকোড অবজেক্টগুলিতে জিনিসগুলি ডিকোড করে এবং বেরোনোর ​​পথে প্রয়োজনীয়ভাবে এনকোড করে যতটা সম্ভব ইউনিকোড অবজেক্টের সাথে ডিল করুন।

যদি আপনার স্ট্রিংটি আসলে একটি ইউনিকোড অবজেক্ট হয় তবে কোনও ফাইলে লেখার আগে আপনাকে এটিকে একটি ইউনিকোড-এনকোডেড স্ট্রিং অবজেক্টে রূপান্তর করতে হবে:

foo = u'Δ, Й, ק, ‎ م, ๗, あ, 叶, 葉, and 말.'
f = open('test', 'w')
f.write(foo.encode('utf8'))
f.close()

আপনি যখন সেই ফাইলটি আবার পড়বেন, আপনি একটি ইউনিকোড-এনকোডেড স্ট্রিং পাবেন যা আপনি একটি ইউনিকোড অবজেক্টে ডিকোড করতে পারেন:

f = file('test', 'r')
print f.read().decode('utf8')

ধন্যবাদ। এটি কোনও ত্রুটি ছাড়াই চলে, তবে তারপরে আমি যদি পাঠ্য ফাইলটি খুলি, আমি একগুচ্ছ অদ্ভুত প্রতীক দেখতে পাচ্ছি :) আমাকে পাঠ্যটি অনুলিপি করে একটি ওয়ার্ডপ্রেস পৃষ্ঠায় আটকানো দরকার (জিজ্ঞাসা করবেন না)। আমি আসলে যে চিহ্নগুলি মুদ্রণ করতে পারি সেখানে কোনও উপায় আছে? আমি অনুমান করি কোনও টেক্সট ফাইল নয়, ডান, তবে অন্য কিছু হতে পারে?
সাইমন

1
আপনি টেক্সট ফাইলটি খুলতে কী ব্যবহার করছেন? আমি অনুমান করছি আপনি উইন্ডোজে আছেন এবং আপনি এটি নোটপ্যাডে খুলছেন যা এনকোডিংগুলির সাথে খুব বুদ্ধিমান নয়। আপনি ওয়ার্ডপ্যাডে এটি খুললে কী ঘটে?
কোয়াস্টিস্টিক

@ কোয়েস্টিওিক ফাইল ফাইল পদ্ধতিটি কোথায় আসে ?
ওমর কুসমা ফেইট

আমার বাইনারি মোড চালু করা দরকার, যেমন f = ওপেন ('পরীক্ষা', 'ডাব্লুবি'), যেমন স্ট্যাকওভারফ্লো . com / a / 5513856 / 6580199-এ বর্ণিত হয়েছে - অন্যথায় আমি "টাইপ-এরর: রাইটিং () যুক্তিটি অবশ্যই str, বাইটস নয় "
বেনজি

72

পাইথন ২.6++ তে আপনি পাইথন 3 এ ডিফল্ট ( বিল্টিন ) ব্যবহারio.open() করতে পারেন :open()

import io

with io.open(filename, 'w', encoding=character_encoding) as file:
    file.write(unicode_text)

আপনার যদি পাঠ্যটি ক্রমবর্ধমানভাবে লেখার প্রয়োজন হয় তবে এটি আরও সুবিধাজনক হতে পারে (আপনার unicode_text.encode(character_encoding)একাধিকবার কল করার প্রয়োজন নেই )। codecsমডিউলটির বিপরীতে , ioমডিউলের একটি যথাযথ সর্বজনীন নিউলাইন সমর্থন রয়েছে।


1
মানুষ, আমি এটি খুঁজতে এত সময় ব্যয় করেছি! ধন্যবাদ!
জর্জি গোবোজভ

2
এটি পাইথন 3 এর জন্যও কাজ করে (সুস্পষ্ট, তবে এখনও দেখানোর পক্ষে মূল্যবান)।
হিপ্পো

37

ইউনিকোড স্ট্রিং হ্যান্ডলিংটি পাইথন 3 এ ইতিমধ্যে মানক করা হয়েছে।

  1. চরগুলি ইতিমধ্যে মেমোরিতে ইউনিকোডে (32-বিট) সঞ্চিত রয়েছে
  2. আপনাকে কেবল utf-8 এ ফাইল খুলতে হবে
    (32-বিট ইউনিকোড থেকে ভেরিয়েবল-বাইট-দৈর্ঘ্যের utf-8 রূপান্তরটি স্বয়ংক্রিয়ভাবে মেমরি থেকে ফাইলের মধ্যে সঞ্চালিত হয়))

    out1 = "(嘉南大圳 ㄐㄧㄚ ㄋㄢˊ ㄉㄚˋ ㄗㄨㄣˋ )"
    fobj = open("t1.txt", "w", encoding="utf-8")
    fobj.write(out1)
    fobj.close()
    

কিন্তু এটি পাইথন 2 এ কাজ করে না, তাই না? (এই পাইথন 3
কোডটিতে

পাইথন ২ এ কাজ করা উচিত নয় We আমরা পাইথন ৩ এ থাকি 3 3 আরও ভাল।
ডেভিড মি লি

18

দ্বারা খোলা ফাইলটি codecs.openএমন একটি ফাইল যা unicodeডেটা নেয় , এটি এনকোড করে এবং iso-8859-1ফাইলটিতে লেখেন। তবে, আপনি যা লেখার চেষ্টা করছেন তা নয় unicode; আপনি unicodeএটি iso-8859-1 নিজের মধ্যে এনকোড করে নিন । unicode.encodeপদ্ধতিটি এটিই করে এবং ইউনিকোড স্ট্রিংকে এনকোড করার ফলাফলটি একটি বাইস্টেরিং (একটি strপ্রকার) is

আপনি হয় স্বাভাবিক ব্যবহার করুন open()এবং ইউনিকোড নিজেই এনকোড করুন, বা (সাধারণত একটি ভাল ধারণা) ব্যবহার করুন codecs.open()এবং ডেটা নিজেই এনকোড করবেন না


17

উপস্থাপনা: আপনার দর্শক কাজ করবে?

আপনার দর্শক / সম্পাদক / টার্মিনালটি (তবে আপনি নিজের utf-8 এনকোডযুক্ত ফাইলের সাথে ইন্টারঅ্যাক্ট করছেন) ফাইলটি পড়তে পারে তা নিশ্চিত করুন। এটি প্রায়শই উইন্ডোজের একটি সমস্যা , উদাহরণস্বরূপ, নোটপ্যাড।

কোনও পাঠ্য ফাইলে ইউনিকোড পাঠ্য লিখছেন?

পাইথন 2 এ, মডিউলটি ব্যবহার openকরুন io(এটি openপাইথন 3 এর বিল্টিনের সমান ):

import io

সেরা অনুশীলন, সাধারণভাবে, UTF-8ফাইলগুলিতে লেখার জন্য ব্যবহার করুন (আমাদের ইউটিএফ -8 দিয়ে বাইট-অর্ডার সম্পর্কেও চিন্তা করতে হবে না)।

encoding = 'utf-8'

utf-8 হ'ল সর্বাধিক আধুনিক এবং সর্বজনীনভাবে ব্যবহারযোগ্য এনকোডিং - এটি সমস্ত ওয়েব ব্রাউজার, বেশিরভাগ পাঠ্য-সম্পাদক (আপনার সমস্যা থাকলে আপনার সেটিংস দেখুন) এবং বেশিরভাগ টার্মিনাল / শেলগুলিতে কাজ করে।

উইন্ডোজে, আপনি চেষ্টা করতে utf-16leপারেন যদি আপনি নোটপ্যাডে (অথবা অন্য কোনও সীমাবদ্ধ দর্শক) সীমাবদ্ধ থাকেন।

encoding = 'utf-16le' # sorry, Windows users... :(

এবং এটি কেবল প্রসঙ্গ পরিচালকের সাথে খুলুন এবং আপনার ইউনিকোড অক্ষরগুলি লিখে দিন:

with io.open(filename, 'w', encoding=encoding) as f:
    f.write(unicode_object)

অনেক ইউনিকোড অক্ষর ব্যবহার উদাহরণ

এখানে একটি উদাহরণ রয়েছে যে ডিজিটাল উপস্থাপনা (পূর্ণসংখ্যায়) থেকে একটি এনকোডযুক্ত মুদ্রণযোগ্য আউটপুট পর্যন্ত এর নামের সাথে, যদি তিনটি বিট প্রশস্ত (4 সর্বাধিক, তবে এটি কিছুটা দূরে চলে যাবে) পর্যন্ত প্রতিটি সম্ভাব্য চরিত্রকে ম্যাপ করার চেষ্টা করে if সম্ভব (এটি নামক কোনও ফাইলে রাখুন uni.py):

from __future__ import print_function
import io
from unicodedata import name, category
from curses.ascii import controlnames
from collections import Counter

try: # use these if Python 2
    unicode_chr, range = unichr, xrange
except NameError: # Python 3
    unicode_chr = chr

exclude_categories = set(('Co', 'Cn'))
counts = Counter()
control_names = dict(enumerate(controlnames))
with io.open('unidata', 'w', encoding='utf-8') as f:
    for x in range((2**8)**3): 
        try:
            char = unicode_chr(x)
        except ValueError:
            continue # can't map to unicode, try next x
        cat = category(char)
        counts.update((cat,))
        if cat in exclude_categories:
            continue # get rid of noise & greatly shorten result file
        try:
            uname = name(char)
        except ValueError: # probably control character, don't use actual
            uname = control_names.get(x, '')
            f.write(u'{0:>6x} {1}    {2}\n'.format(x, cat, uname))
        else:
            f.write(u'{0:>6x} {1}  {2}  {3}\n'.format(x, cat, char, uname))
# may as well describe the types we logged.
for cat, count in counts.items():
    print('{0} chars of category, {1}'.format(count, cat))

এটি প্রায় এক মিনিটের ক্রম অনুসারে চলতে হবে এবং আপনি ডেটা ফাইলটি দেখতে পারবেন এবং যদি আপনার ফাইল প্রদর্শক ইউনিকোড প্রদর্শন করতে পারেন তবে আপনি এটি দেখতে পাবেন। বিভাগগুলি সম্পর্কিত তথ্য এখানে পাওয়া যাবে । গণনার উপর ভিত্তি করে, আমরা সম্ভবত সিএন এবং কো বিভাগগুলি বাদ দিয়ে আমাদের ফলাফলগুলি উন্নত করতে পারি, যার কোনও চিহ্ন নেই।

$ python uni.py

এটি হেক্সাডেসিমাল ম্যাপিং, বিভাগ , প্রতীক (নাম না পেলে সম্ভবত একটি নিয়ন্ত্রণ চরিত্র) এবং প্রতীকটির নাম প্রদর্শন করবে। যেমন

আমি lessইউনিক্স বা সাইগউইনকে প্রস্তাব দিই (আপনার আউটপুটে পুরো ফাইলটি মুদ্রণ / বিড়াল করবেন না):

$ less unidata

উদাহরণস্বরূপ পাইথন 2 (ইউনিকোড 5.2) ব্যবহার করে আমি এটি থেকে যে নমুনাগুলি তৈরি করেছি তার অনুরূপ প্রদর্শিত হবে:

     0 Cc NUL
    20 Zs     SPACE
    21 Po  !  EXCLAMATION MARK
    b6 So    PILCROW SIGN
    d0 Lu  Ð  LATIN CAPITAL LETTER ETH
   e59 Nd    THAI DIGIT NINE
  2887 So    BRAILLE PATTERN DOTS-1238
  bc13 Lo    HANGUL SYLLABLE MIH
  ffeb Sm    HALFWIDTH RIGHTWARDS ARROW

অ্যানাকোন্ডার আমার পাইথন 3.5 এর ইউনিকোড 8.0 রয়েছে, আমি বেশিরভাগ 3 এর মত অনুমান করব।


3

কীভাবে কোনও ফাইলে ইউনিকোড অক্ষর মুদ্রণ করবেন:

এটি ফাইলটিতে সংরক্ষণ করুন: foo.py:

#!/usr/bin/python -tt
# -*- coding: utf-8 -*-
import codecs
import sys 
UTF8Writer = codecs.getwriter('utf8')
sys.stdout = UTF8Writer(sys.stdout)
print(u'e with obfuscation: é')

এটি চালান এবং ফাইলের পাইপ আউটপুট:

python foo.py > tmp.txt

Tmp.txt খুলুন এবং ভিতরে দেখুন, আপনি এটি দেখতে পাবেন:

el@apollo:~$ cat tmp.txt 
e with obfuscation: é

সুতরাং আপনি ইউনিকোড ই সংরক্ষণ করে একটি ফাইলের মধ্যে এটি একটি বিস্মৃত চিহ্ন দিয়ে রেখেছেন।


2
আমি এই উত্তরটি সম্পর্কে বেশ উত্তেজিত ছিলাম, তবে এটি আমার মেশিনে একটি ত্রুটি দেয় gives যখন আমি কপি / আপনার কোড পেস্ট করুন, আমি কোনো ত্রুটির সম্মুখীন হয়েছেন: "TypeError Str হতে হবে, বাইট নয়"
রিচার্ড Rast

1

আপনি যখন কোনও অ-ইউনিকোড স্ট্রিং এনকোড করার চেষ্টা করবেন তখন এই ত্রুটিটি দেখা দেয়: এটি এটিকে সাদামাটা ASCII তে ধরে ধরেই এটি ডিকোড করার চেষ্টা করে। দুটি সম্ভাবনা রয়েছে:

  1. আপনি এটিকে বাইস্টেরিংয়ের সাথে এনকোড করছেন তবে আপনি কোডেস.ওপেন ব্যবহার করেছেন বলে লেখার পদ্ধতিটি একটি ইউনিকোড অবজেক্টের প্রত্যাশা করে। সুতরাং আপনি এটিকে এনকোড করুন এবং এটি আবার ডিকোড করার চেষ্টা করে। চেষ্টা করুন: f.write(all_html)পরিবর্তে।
  2. all_html আসলে কোনও ইউনিকোড অবজেক্ট নয়। আপনি যখন করেন .encode(...), এটি প্রথমে এটি ডিকোড করার চেষ্টা করে।

0

পাইথন 3 তে লেখার ক্ষেত্রে

>>> a = u'bats\u00E0'
>>> print a
batsà
>>> f = open("/tmp/test", "w")
>>> f.write(a)
>>> f.close()
>>> data = open("/tmp/test").read()
>>> data
'batsà'

পাইথন 2 এ লেখার ক্ষেত্রে:

>>> a = u'bats\u00E0'
>>> f = open("/tmp/test", "w")
>>> f.write(a)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)

এই ত্রুটিটি এড়াতে আপনাকে এটিকে "utf-8" এর মতো কোডেক ব্যবহার করে বাইটে এনকোড করতে হবে:

>>> f.write(a.encode("utf-8"))
>>> f.close()

এবং কোডেকগুলি "utf-8" ব্যবহার করার সময় ডেটা ডিকোড করুন:

>>> data = open("/tmp/test").read()
>>> data.decode("utf-8")
u'bats\xe0'

এবং আপনি যদি এই স্ট্রিংয়ে মুদ্রণ চালানোর চেষ্টা করেন তবে এটি স্বয়ংক্রিয়ভাবে এই "utf-8" কোডেকগুলি ব্যবহার করে ডিকোড হবে

>>> print a
batsà
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.