আমি এমন কিছু পাঠ্য পেয়েছি যা এনকোড করা আছে তবে আমি জানি না কী চরসেটটি ব্যবহৃত হয়েছিল। পাইথন ব্যবহার করে কোনও পাঠ্য ফাইলের এনকোডিং নির্ধারণ করার কোনও উপায় আছে কি? আমি কীভাবে একটি টেক্সট ফাইলের এনকোডিং / কোডপেজ সি # এর সাথে সনাক্ত করতে পারি ।
আমি এমন কিছু পাঠ্য পেয়েছি যা এনকোড করা আছে তবে আমি জানি না কী চরসেটটি ব্যবহৃত হয়েছিল। পাইথন ব্যবহার করে কোনও পাঠ্য ফাইলের এনকোডিং নির্ধারণ করার কোনও উপায় আছে কি? আমি কীভাবে একটি টেক্সট ফাইলের এনকোডিং / কোডপেজ সি # এর সাথে সনাক্ত করতে পারি ।
উত্তর:
সব সময় এনকোডিংটি সঠিকভাবে সনাক্ত করা অসম্ভব ।
(চার্ডেট এফএকিউ থেকে :)
তবে কিছু এনকোডিংগুলি নির্দিষ্ট ভাষার জন্য অনুকূলিত হয় এবং ভাষা এলোমেলো নয়। কিছু চরিত্রের ক্রম সমস্ত সময় পপ আপ হয়, অন্য সিকোয়েন্সগুলি কোনও অর্থ দেয় না। ইংরেজিতে সাবলীল একজন ব্যক্তি যিনি একটি সংবাদপত্র খোলেন এবং "txzqJv 2! Dasd0a QqdKjvz" তাত্ক্ষণিকভাবে স্বীকৃতি পাবেন যে এটি ইংরেজি নয় (যদিও এটি পুরোপুরি ইংরেজি অক্ষর দ্বারা রচিত)। প্রচুর "সাধারণ" পাঠ্য অধ্যয়ন করে একটি কম্পিউটার অ্যালগরিদম এই ধরণের সাবলীল অনুকরণ করতে পারে এবং কোনও পাঠ্যের ভাষা সম্পর্কে একটি শিক্ষিত অনুমান করতে পারে।
এখানে চারডেট লাইব্রেরি রয়েছে যা অধ্যয়নটি এনকোডিং সনাক্ত করার চেষ্টা করার জন্য ব্যবহার করে। চারডেট মোজিলায় স্বয়ং-সনাক্তকরণ কোডের একটি বন্দর।
আপনি ইউনিকোডড্যামিটও ব্যবহার করতে পারেন । এটি নিম্নলিখিত পদ্ধতিগুলি চেষ্টা করবে:
এনকোডিংয়ের কাজ করার জন্য আরেকটি বিকল্প হ'ল লিবমাজিক (যা ফাইল কমান্ডের পিছনে কোড ) ব্যবহার করা। পাইথন বাইন্ডিংয়ের একটি ধারণা পাওয়া যায়।
ফাইল উত্স ট্রিতে থাকা পাইথন বাইন্ডিংগুলি পাইথন-ম্যাজিক (বা পাইথন 3-ম্যাজিক ) ডেবিয়ান প্যাকেজ হিসাবে উপলব্ধ। এটি এটি করে একটি ফাইলের এনকোডিং নির্ধারণ করতে পারে:
import magic
blob = open('unknown-file', 'rb').read()
m = magic.open(magic.MAGIC_MIME_ENCODING)
m.load()
encoding = m.buffer(blob) # "utf-8" "us-ascii" etc
পাইপিতে অজানা , তবে অসম্পূর্ণ, পাইথন-ম্যাজিক পাইপ প্যাকেজ রয়েছে যা এটি ব্যবহার করে libmagic
। এটি করে এনকোডিংটি পেতে পারে:
import magic
blob = open('unknown-file', 'rb').read()
m = magic.Magic(mime_encoding=True)
encoding = m.from_buffer(blob)
libmagic
প্রকৃতপক্ষে এটি একটি কার্যকর বিকল্প chardet
। এবং পৃথক প্যাকেজগুলির নামকরণের দুর্দান্ত তথ্য python-magic
! আমি নিশ্চিত যে এই অস্পষ্টতা অনেককে কামড় দেয়
file
পাঠ্য ফাইলগুলিতে মানব ভাষা সনাক্তকরণে বিশেষ ভাল নয়। এটি বিভিন্ন ধারক বিন্যাস শনাক্ত করার জন্য দুর্দান্ত, যদিও আপনাকে মাঝে মাঝে এটির অর্থ কী তা জানতে হবে ("মাইক্রোসফ্ট অফিস ডকুমেন্ট" এর অর্থ একটি আউটলুক বার্তা ইত্যাদি হতে পারে)।
open()
: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 169799: invalid start byte
। ফাইল তেজ অনুযায়ী এনকোডিং :set fileencoding
হয় latin1
।
errors='ignore'
, উদাহরণ কোডটির আউটপুট কম সহায়ক binary
।
কিছু এনকোডিং কৌশল, স্বাদ নিতে দয়া করে অস্বীকার করুন:
#!/bin/bash
#
tmpfile=$1
echo '-- info about file file ........'
file -i $tmpfile
enca -g $tmpfile
echo 'recoding ........'
#iconv -f iso-8859-2 -t utf-8 back_test.xml > $tmpfile
#enca -x utf-8 $tmpfile
#enca -g $tmpfile
recode CP1250..UTF-8 $tmpfile
আপনি একটি লুপের আকারে ফাইলটি খোলার এবং পড়ে এই এনকোডিং পরীক্ষা করতে পছন্দ করতে পারেন ... তবে আপনাকে প্রথমে ফাইলসাইজটি পরীক্ষা করতে হবে:
encodings = ['utf-8', 'windows-1250', 'windows-1252' ...etc]
for e in encodings:
try:
fh = codecs.open('file.txt', 'r', encoding=e)
fh.readlines()
fh.seek(0)
except UnicodeDecodeError:
print('got unicode error with %s , trying different encoding' % e)
else:
print('opening the file with encoding: %s ' % e)
break
এখানে chardet
এনকোডিংয়ের পূর্বাভাসটি পড়ার এবং গ্রহণের মূল্য গ্রহণের উদাহরণ রয়েছে n_lines
, ফাইলটি বড় হওয়াতে এটি পড়া ।
chardet
confidence
এটির একটি এনকোডিং পূর্বাভাস (যেমন ) এর সম্ভাবনাও দেয় (যেমনটি তারা কীভাবে সামনে আসে তা দেখে না) যা এর পূর্বাভাস দিয়ে ফিরে আসে chardet.predict()
, যাতে আপনি যদি পছন্দ করেন তবে কোনওভাবেই এটি কাজ করতে পারেন।
def predict_encoding(file_path, n_lines=20):
'''Predict a file's encoding using chardet'''
import chardet
# Open the file as binary data
with open(file_path, 'rb') as f:
# Join binary lines for specified number of lines
rawdata = b''.join([f.readline() for _ in range(n_lines)])
return chardet.detect(rawdata)['encoding']
def predict_encoding(file_path, n=20): ... skip ... and then rawdata = b''.join([f.read() for _ in range(n)])
পাইথন ৩.6 এ এই ফাংশনটি চেষ্টা করে দেখেছি, "এসকিআই", "সিপি 1252", "ইউটিএফ -8", "ইউনিকোড" এনকোডিংগুলির সাথে পুরোপুরি কাজ করেছেন। সুতরাং এটি অবশ্যই upvote।
# Function: OpenRead(file)
# A text file can be encoded using:
# (1) The default operating system code page, Or
# (2) utf8 with a BOM header
#
# If a text file is encoded with utf8, and does not have a BOM header,
# the user can manually add a BOM header to the text file
# using a text editor such as notepad++, and rerun the python script,
# otherwise the file is read as a codepage file with the
# invalid codepage characters removed
import sys
if int(sys.version[0]) != 3:
print('Aborted: Python 3.x required')
sys.exit(1)
def bomType(file):
"""
returns file encoding string for open() function
EXAMPLE:
bom = bomtype(file)
open(file, encoding=bom, errors='ignore')
"""
f = open(file, 'rb')
b = f.read(4)
f.close()
if (b[0:3] == b'\xef\xbb\xbf'):
return "utf8"
# Python automatically detects endianess if utf-16 bom is present
# write endianess generally determined by endianess of CPU
if ((b[0:2] == b'\xfe\xff') or (b[0:2] == b'\xff\xfe')):
return "utf16"
if ((b[0:5] == b'\xfe\xff\x00\x00')
or (b[0:5] == b'\x00\x00\xff\xfe')):
return "utf32"
# If BOM is not provided, then assume its the codepage
# used by your operating system
return "cp1252"
# For the United States its: cp1252
def OpenRead(file):
bom = bomType(file)
return open(file, 'r', encoding=bom, errors='ignore')
#######################
# Testing it
#######################
fout = open("myfile1.txt", "w", encoding="cp1252")
fout.write("* hi there (cp1252)")
fout.close()
fout = open("myfile2.txt", "w", encoding="utf8")
fout.write("\u2022 hi there (utf8)")
fout.close()
# this case is still treated like codepage cp1252
# (User responsible for making sure that all utf8 files
# have a BOM header)
fout = open("badboy.txt", "wb")
fout.write(b"hi there. barf(\x81\x8D\x90\x9D)")
fout.close()
# Read Example file with Bom Detection
fin = OpenRead("myfile1.txt")
L = fin.readline()
print(L)
fin.close()
# Read Example file with Bom Detection
fin = OpenRead("myfile2.txt")
L =fin.readline()
print(L) #requires QtConsole to view, Cmd.exe is cp1252
fin.close()
# Read CP1252 with a few undefined chars without barfing
fin = OpenRead("badboy.txt")
L =fin.readline()
print(L)
fin.close()
# Check that bad characters are still in badboy codepage file
fin = open("badboy.txt", "rb")
fin.read(20)
fin.close()
আপনার প্ল্যাটফর্মের উপর নির্ভর করে, আমি কেবল লিনাক্স শেল file
কমান্ডটি ব্যবহার করতে পছন্দ করি । এটি আমার পক্ষে কাজ করে যেহেতু আমি এটি কোনও স্ক্রিপ্টে ব্যবহার করছি যা একচেটিয়াভাবে আমাদের লিনাক্স মেশিনগুলির মধ্যে চলে runs
স্পষ্টতই এটি আদর্শ সমাধান বা উত্তর নয়, তবে এটি আপনার প্রয়োজন অনুসারে পরিবর্তন করা যেতে পারে। আমার ক্ষেত্রে আমাকে কেবল ফাইলটি ইউটিএফ -8 কিনা তা নির্ধারণ করতে হবে।
import subprocess
file_cmd = ['file', 'test.txt']
p = subprocess.Popen(file_cmd, stdout=subprocess.PIPE)
cmd_output = p.stdout.readlines()
# x will begin with the file type output as is observed using 'file' command
x = cmd_output[0].split(": ")[1]
return x.startswith('UTF-8')
নীতিগতভাবে, সাধারণ ক্ষেত্রে কোনও পাঠ্য ফাইলের এনকোডিং নির্ধারণ করা অসম্ভব। সুতরাং না, এটি করার জন্য কোনও পাইথন লাইব্রেরি নেই।
আপনার যদি পাঠ্য ফাইলটি সম্পর্কে আরও নির্দিষ্ট জ্ঞান থাকে (উদাহরণস্বরূপ এটি এটি এক্সএমএল), গ্রন্থাগারের কার্যকারিতা থাকতে পারে।
আপনি যদি ফাইলটির কিছু সামগ্রী জানেন তবে আপনি এটি বেশ কয়েকটি এনকোডিং দিয়ে ডিকোড করার চেষ্টা করতে পারেন এবং এটি অনুপস্থিত রয়েছে তা দেখতে পারেন। সাধারণত কোনও উপায় নেই যেহেতু একটি পাঠ্য ফাইল একটি পাঠ্য ফাইল এবং সেগুলি বোকা;)
এই সাইটে অ্যাসিআইকে স্বীকৃতি দেওয়ার জন্য, বোমগুলির সাথে এনকোডিং করার জন্য এবং অ বোফ নম্বরের জন্য পাইথন কোড রয়েছে: https://unicodebook.readthedocs.io/guess_encoding.html । বাইট অ্যারে (ডেটা) এ ফাইলটি পড়ুন: http://www.codecodex.com/wiki/Read_a_file_into_a_byte_array । এখানে একটি উদাহরণ। আমি অক্সে আছি
#!/usr/bin/python
import sys
def isUTF8(data):
try:
decoded = data.decode('UTF-8')
except UnicodeDecodeError:
return False
else:
for ch in decoded:
if 0xD800 <= ord(ch) <= 0xDFFF:
return False
return True
def get_bytes_from_file(filename):
return open(filename, "rb").read()
filename = sys.argv[1]
data = get_bytes_from_file(filename)
result = isUTF8(data)
print(result)
PS /Users/js> ./isutf8.py hi.txt
True
chardet
রেফারেন্সের জন্য ধন্যবাদ । কিছুটা ধীর হলেও ভাল লাগছে।