স্ট্রিং ক্রিয়াকলাপগুলিতে পাইথন ইন্টারপ্রেটারকে কীভাবে সঠিকভাবে নন-এএসসিআইআই অক্ষর পরিচালনা করতে হয়?


104

আমার কাছে একটি স্ট্রিং রয়েছে যা দেখতে এমন দেখাচ্ছে:

6 918 417 712

এই স্ট্রিংটি ছাঁটাই করার পরিষ্কার কাট উপায়টি (যেমন আমি পাইথন বুঝি) স্ট্রিংটি একটি ভেরিয়েবলের মধ্যে কেবল বলা হয় s, আমরা পাই:

s.replace('Â ', '')

কৌতুক করা উচিত। তবে অবশ্যই এটি অভিযোগ করে যে '\xc2'ফাইল ব্লাবলা.পি -তে নন-এএসসিআইআই চরিত্রটি এনকোড করা হয়নি।

আমি কখনই বুঝতে পারি না কীভাবে বিভিন্ন এনকোডিংয়ের মধ্যে স্যুইচ করতে হয়।

এখানে কোডটি দেওয়া আছে, এটি সত্যিই উপরের মতো একই, তবে এখন এটি প্রসঙ্গে। নোটপ্যাডে ফাইলটি ইউটিএফ -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 টি উত্তরের সব চেষ্টা করেছেন। যাও না। তবুও ইউনিকোড ডিকোড এরিয়ারটি পাওয়া যাচ্ছে: 'এসকিআই' কোডেক বাইট 0xc2 পজিশন 1 এ পঠন করতে পারে না: অমিতিকাল পরিসীমা (128) নয়
অ্যাডারগার্ড

আপনার ইউনিকোড স্ট্রিং অবশ্যই বন্ধ করতে হবেu
সাইলেন্টগোস্ট

@ সাইলেন্টগোস্ট: আপনি দেখতে পাচ্ছেন যে এটি কোনও ইউনিকোড স্ট্রিং কিনা তা নিশ্চিত হওয়ার কোনও উপায় নেই। আমি একটি স্ট্রিং পেয়েছি যা উপরে প্রদর্শিত সামগ্রী আছে তবে এতে অ্যাস্কি স্ট্রিং নেই। এটাই আসল সমস্যা। আমি এটা ইউনিকোড, যেহেতু এটি প্রথম 128. নয় অনুমান করছি
adergaard

ত্রুটিটির আগত স্ট্রিংয়ের সাথে কোনও সম্পর্ক নেই। এটি আপনার কোডের একটি স্ট্রিং যা এই ত্রুটিটি উত্থাপন করে!
সাইলেন্টগোস্ট

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)

মনে রাখবেন যে এটি ইউটিএফ -8 এনকোডিংয়ের সাথে কাজ করার গ্যারান্টিযুক্ত (কারণ মাল্টি-বাইট অক্ষরের সমস্ত বাইটের মধ্যে সর্বাধিক বিট সেট 1 রয়েছে)।


1
আমি পেয়েছি: TypeError: অর্ডার () একটি চরিত্রের প্রত্যাশা করেছিল, তবে দৈর্ঘ্যের 2 টি স্ট্রিং পাওয়া গেছে
আইভলিন

@ ইভলিন কারণ "অক্ষর "টিকে যথাযথ ইউনিকোড হিসাবে ব্যাখ্যা করা হচ্ছে না ... আপনার উত্সের স্ট্রিংটি uযদি আক্ষরিক হয় তবে এটির সাথে উপসর্গ করা হয়েছে কিনা তা পরীক্ষা করুন ।
ফরট্রান

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

4
আপনি যে ভোট পেয়েছেন তা আমি দেখতে পাচ্ছি কিন্তু আমি যখন চেষ্টা করে দেখি তখন তা হয়: না। ইউনিকোড ডিকোডেরর: 'এসকিআই' কোডেক বাইট 0xc2 পজিশন 1 তে ডিকোড করতে পারে না: অরডিনাল রেঞ্জ নয় (128)। এটা কি আমার অরিগনাল স্ট্রিংটি ইউনিকোডে নেই? ভাল যে কোনও ক্ষেত্রে। এটি প্রয়োজন
অ্যাডারগার্ড

2
সুন্দর ধন্যবাদ. মূল কোডিংয়ে পাওয়ার জন্য আমি .decode () ব্যবহারের পরামর্শ দিতে পারি?
আকিরস

আপনি যদি ইউনিকোডডেকোডেরর: 'এসকিআই' পাচ্ছেন তবে এনকোডিং ফাংশন প্রয়োগের আগে স্ট্রিংটিকে '' ইউটিএফ -8 'ফর্ম্যাটে রূপান্তর করার চেষ্টা করুন।
সতীশ

16

নিম্নলিখিত কোডটি সমস্ত ASCII অক্ষরকে প্রশ্ন চিহ্নের সাথে প্রতিস্থাপন করবে।

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

কৌতূহলের বাইরে আমি জানতে চেয়েছিলাম, প্রশ্ন চিহ্নের সাথে এটি প্রতিস্থাপনের কোনও নির্দিষ্ট কারণ আছে কি?
মহসিন


5

উত্তরের জন্য বেশ দেরি হলেও মূল স্ট্রিংটি ইউটিএফ -8 এ ছিল এবং '\ xc2 \ xa0' হ'ল নো-BREAK স্পেসের জন্য ইউটিএফ -8। s.decode('utf-8')উইন্ডোজ -১২২২ বা ল্যাটিন -১ হিসাবে ভুলভাবে ডিকোড করার সময় ( স্ট্রিং হিসাবে a xa0 প্রদর্শিত হবে) হিসাবে মূল স্ট্রিংটিকে কেবল ডিকোড করুন :

উদাহরণ (পাইথন 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


নাঃ। ইউনিকোড ডিকোডেরর: 'এসকিআই' কোডেক বাইট 0xc2 পজিশন 1 তে ডিকোড করতে পারে না: অরডিনাল রেঞ্জ নয় (128)। এটা কি আমার অরিগনাল স্ট্রিংটি ইউনিকোডে নেই? ভাল যে কোনও ক্ষেত্রে। আমি সম্ভবত কিছু ভুল করছি।
অ্যাডারগার্ড

@ অ্যাডারগার্ড, আপনি কি উত্স ফাইলের শীর্ষে # - - কোডিং: utf-8 - যোগ করেছেন?
নাদিয়া আলরামলি

হ্যাঁ, এই পৃষ্ঠার আবারও দেখুন, আমি কোয়েস্টইন সম্পাদনা করেছি এবং কোড এবং শিরোনামের মন্তব্য রেখেছি। সাহায্যের জন্য ধন্যবাদ.
অ্যাডারগার্ড

আমি মনে করি আপনি ইউনিকোডে এইচটিএমএল বা এক্সএমএল ডকুমেন্ট থেকে স্ট্রিংগুলি কীভাবে পাবেন তা নির্ধারণ করতে হবে। এখানে আরও তথ্য: 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'

পাইথন ২.6 দিয়ে শুরু করে আপনি কোনওটি টেবিলটি সেট করতে পারেন এবং http://docs.python.org/library/stdtypes- এ স্ট্যান্ডার্ড ডক্সে দেখানো উদাহরণগুলির মতো আপনি চান না এমন অক্ষরগুলি মুছতে মুছতে সক্ষম ব্যবহার করতে পারেন । এইচটিএমএল

ইউনিকোড স্ট্রিং সহ, অনুবাদ টেবিলটি 256-অক্ষরের স্ট্রিং নয় বরং কী হিসাবে প্রাসঙ্গিক অক্ষরের অর্ড () দিয়ে ডিক হয়। তবে যাইহোক, ইউনিকোড স্ট্রিং থেকে যথাযথ ascii স্ট্রিং পাওয়া উপরের ট্রুপো দ্বারা উল্লিখিত পদ্ধতিটি ব্যবহার করে যথেষ্ট সহজ, যথা: ইউনিকোড_স্ট্রিং.ইনকোড ("ascii", "উপেক্ষা")

সংক্ষিপ্তসার হিসাবে, যদি কোনও কারণে আপনাকে একেবারে এসকি স্ট্রিংয়ের প্রয়োজন হয় (উদাহরণস্বরূপ, আপনি যখন এর সাথে একটি আদর্শ ব্যতিক্রম উত্থাপন করেন 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)

অনুবাদটির সাথে ভাল জিনিসটি হ'ল আপনি প্রকৃতপক্ষে উচ্চারণযুক্ত অক্ষরগুলিকে কেবল মুছে ফেলার পরিবর্তে বা '' 'দ্বারা প্রতিস্থাপনের পরিবর্তে প্রাসঙ্গিক অ-উচ্চারণযুক্ত আসকি চরিত্রগুলিতে রূপান্তর করতে পারেন । উদাহরণস্বরূপ সূচিকরণের জন্য এটি প্রায়শই দরকারী।


আমি পেয়েছি: TypeError: চরিত্রের মানচিত্রটি অবশ্যই পূর্ণসংখ্যক,
কোনওটিই

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 অক্ষর সেটের মধ্যেও হতে পারে তবে এমন একটি চরিত্র যা আপনি প্রত্যাশা করেননি।

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