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


100

আমি একটি টেক্সট ফাইল নিয়ে কাজ করছি। আমি নন-এএসসিআইআই অক্ষরবিহীন ফাইল থেকে পাঠ্যের একটি স্ট্রিং চাই। তবে আমি স্পেস এবং পিরিয়ড ছেড়ে যেতে চাই। বর্তমানে, আমি সেগুলিও ছিনিয়ে নিচ্ছি। কোডটি এখানে:

def onlyascii(char):
    if ord(char) < 48 or ord(char) > 127: return ''
    else: return char

def get_my_string(file_path):
    f=open(file_path,'r')
    data=f.read()
    f.close()
    filtered_data=filter(onlyascii, data)
    filtered_data = filtered_data.lower()
    return filtered_data

স্পেস এবং পিরিয়ডগুলি ছেড়ে যাওয়ার জন্য কীভাবে আমি কেবলমাত্র () পরিবর্তন করব? আমি ধারণা করি এটি খুব জটিল নয় তবে আমি তা বুঝতে পারি না।


ধন্যবাদ (আন্তরিকভাবে) জন স্পষ্টির জন্য। আমি বুঝতে পারি যে স্পেস এবং পিরিয়ডগুলি ASCII অক্ষর। তবে আমি কেবল দু'টি ASCII অক্ষর মুছে ফেলার চেষ্টা করার সময় উভয়কে অনিচ্ছাকৃতভাবে মুছে ফেলছিলাম। আমি দেখছি কীভাবে আমার প্রশ্নটি অন্যথায় বোঝায়।

@ পলিটিক্যাল ইকোনমিস্ট: আপনার সমস্যাটি এখনও খুব নীচে নির্দিষ্ট। আমার উত্তর দেখুন।
জন মাচিন

উত্তর:


187

আপনি স্ট্রিং থেকে সমস্ত অক্ষর ফিল্টার করতে পারেন যা স্ট্রিং.প্রিন্টেবল ব্যবহার করে মুদ্রণযোগ্য নয় , এর মতো:

>>> s = "some\x00string. with\x15 funny characters"
>>> import string
>>> printable = set(string.printable)
>>> filter(lambda x: x in printable, s)
'somestring. with funny characters'

আমার মেশিনে স্ট্রিং.প্রিন্টেবল রয়েছে:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c

সম্পাদনা: পাইথন 3 এ, ফিল্টার একটি পুনরাবৃত্তযোগ্য ফিরে আসবে। কোনও স্ট্রিং ফিরে পাওয়ার সঠিক উপায়টি হ'ল:

''.join(filter(lambda x: x in printable, s))

2
অর্ডিনাল 48 এর নীচে থাকা মুদ্রণযোগ্য চরগুলি কী হবে?
joaquin

38
ব্যবহারে একমাত্র সমস্যা filterহ'ল এটি একটি পুনরাবৃত্তযোগ্য ফেরত দেয়। আপনি একটি স্ট্রিং ফেরত চাই থাকেন (যেমন আমি, কারণ আমি এই প্রয়োজন যখন তালিকার কম্প্রেশন করছেন করেনি) তাহলে এই কাজ: ''.join(filter(lambda x: x in string.printable, s)
সিজেবার্থ

5
@ সিজেবার্থ - মন্তব্যটি অজগর 3 নির্দিষ্ট, তবে খুব দরকারী। ধন্যবাদ!
undershock

7
কেন রেগুলার এক্সপ্রেশন ব্যবহার করবেন: re.sub(r'[^\x00-\x7f]',r'', your-non-ascii-string)। এই থ্রেডটি দেখুন স্ট্যাকওভারফ্লো.com
নোয়াম মানস

1
@ নোমমনোস এটি আমার জন্য 4-5 গুণ দ্রুত গতিতে যোগ দিয়েছিল ... ফিল্টার ... ল্যাম্বদা সমাধান, ধন্যবাদ।
artfulrobot

95

ভিন্ন কোডেকে পরিবর্তনের একটি সহজ উপায় হ'ল এনকোড () বা ডিকোড () ব্যবহার করে। আপনার ক্ষেত্রে, আপনি ASCII এ রূপান্তর করতে চান এবং সমর্থিত নয় এমন সমস্ত প্রতীক উপেক্ষা করতে চান। উদাহরণস্বরূপ, সুইডিশ অক্ষর একটি ASCII অক্ষর নয়:

    >>>s = u'Good bye in Swedish is Hej d\xe5'
    >>>s = s.encode('ascii',errors='ignore')
    >>>print s
    Good bye in Swedish is Hej d

সম্পাদনা:

পাইথন 3: টিআর -> বাইটস -> স্ট্রিম

>>>"Hej då".encode("ascii", errors="ignore").decode()
'hej d'

পাইথন 2: ইউনিকোড -> স্ট্র -> ইউনিকোড

>>> u"hej då".encode("ascii", errors="ignore").decode()
u'hej d'

পাইথন 2: স্ট্র -> ইউনিকোড -> স্ট্র (বিপরীত ক্রমে ডিকোড এবং এনকোড)

>>> "hej d\xe5".decode("ascii", errors="ignore").encode()
'hej d'

16
আমি পেয়েছিUnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 27
Xodarap777

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

2
কেবল পাই 3 এ কাজ করে তবে এটি মার্জিত।
চমত্কার

7
যারা @ Xodarap777 এর সমান ত্রুটি পেয়েছেন তাদের জন্য: আপনার প্রথমে স্ট্রিং।) ডেকড করা উচিত, এবং কেবলমাত্র সেই এনকোডের পরে। উদাহরণস্বরূপs.decode('utf-8').encode('ascii', errors='ignore')
Spc_555

30

@Artfulrobot এর মতে এটি ফিল্টার এবং ল্যাম্বডারের চেয়ে দ্রুত হওয়া উচিত:

re.sub(r'[^\x00-\x7f]',r'', your-non-ascii-string) 

এখানে আরও উদাহরণ দেখুন http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20079244#20079244


1
এই সমাধানটি ওপির বর্ণিত প্রশ্নের উত্তর দেয়, তবে সাবধান থাকুন যে এটি ASCII এর অন্তর্ভুক্ত থাকা মুদ্রণযোগ্য অক্ষরগুলি মুছে ফেলবে না যা আমি মনে করি যে ওপি জিজ্ঞাসা করার ইচ্ছা করেছিল।
ড্যানিলো সুজা মরিজেস

6

আপনার প্রশ্নটি অস্পষ্ট; প্রথম দুটি বাক্য এক সাথে নেওয়া বোঝায় যে আপনি বিশ্বাস করেন যে স্থান এবং "পিরিয়ড" অ ASCII অক্ষর। এটি ভুল। সমস্ত অক্ষর যেমন আদেশ (চর) <= 127 ASCII অক্ষর। উদাহরণস্বরূপ, আপনার ফাংশনটি এই অক্ষরগুলি বাদ দেয়! "# $% & \ '() * +, -। / তবে বেশ কয়েকটি অন্যান্য যেমন [] {} অন্তর্ভুক্ত}

দয়া করে পিছনে যান, কিছুটা চিন্তা করুন এবং ASCII শব্দের উল্লেখ না করে আপনি কী করতে চাইছেন তা জানানোর জন্য আপনার প্রশ্নটি সম্পাদনা করুন এবং আপনি কেন এমন অর্ডার (চর)> = 128 কে অগ্রাহ্য বলে মনে করেন? এছাড়াও: পাইথনের কোন সংস্করণ? আপনার ইনপুট ডেটাটির এনকোডিং কী?

দয়া করে নোট করুন যে আপনার কোডটি পুরো ইনপুট ফাইলটিকে একটি একক স্ট্রিং হিসাবে পড়ে এবং অন্য একটি উত্তরের জন্য আপনার মন্তব্য ("দুর্দান্ত সমাধান") বোঝায় যে আপনি আপনার ডেটাতে নতুন লাইনের বিষয়ে যত্নশীল নন। যদি আপনার ফাইলে দুটি লাইন থাকে:

this is line 1
this is line 2

ফলাফল হবে 'this is line 1this is line 2'... আপনি কি সত্যিই এটি চান?

একটি বৃহত্তর সমাধান অন্তর্ভুক্ত হবে:

  1. ফিল্টার ফাংশন চেয়ে ভাল নাম onlyascii
  2. যদি তর্কটি ধরে রাখা হয় তবে একটি ফিল্টার ফাংশনটি কেবল সত্যের মানটি ফিরিয়ে আনতে পারে:

    def filter_func(char):
        return char == '\n' or 32 <= ord(char) <= 126
    # and later:
    filtered_data = filter(filter_func, data).lower()

এই উত্তরটি আমরা ওপি-তে অনুরূপ কিছু জিজ্ঞাসা করতে আসাদের পক্ষে খুব সহায়ক এবং আপনার প্রস্তাবিত উত্তরটি সহায়কভাবে পাইথোনিক। যাইহোক, আমি এটি আশ্চর্যজনক মনে করি যে আপনি এটি ব্যাখ্যা করার সাথে সাথে সমস্যার আরও কার্যকর সমাধান নেই (যা আমি প্রায়শই চালিত করি) - চরিত্র অনুসারে, এটি একটি খুব বড় ফাইলে খুব দীর্ঘ সময় নেয়।
Xodarap777

5

আপনি অ-ইংরেজি অক্ষরগুলি সরাতে নিম্নলিখিত কোডটি ব্যবহার করতে পারেন:

import re
str = "123456790 ABC#%? .(朱惠英)"
result = re.sub(r'[^\x00-\x7f]',r'', str)
print(result)

এই ফিরে আসবে

123456790 এবিসি #%? । ()


1

আপনি যদি মুদ্রণযোগ্য আসকি অক্ষর চান তবে আপনার কোডটি অবশ্যই সংশোধন করতে হবে:

if ord(char) < 32 or ord(char) > 126: return ''

এটি string.printableরিটার্ন এবং ট্যাব ('\ t', '\ n', '\ x0b', '\ x0c' এবং '\ r') ব্যতীত (@ জেটেরাস থেকে উত্তর) এর সমান, তবে এর সাথে মিলছে না আপনার প্রশ্নের পরিসীমা


1
কিছুটা সহজ: ল্যাম্বদা এক্স: 32 <= অর্ড (এক্স) <= 126
জেটেরেস

এটি স্ট্রিং.প্রিন্টের মতো নয় কারণ এটি স্ট্রিং.ওয়াইটস স্পেস ছেড়ে চলেছে, যদিও এটি ওপি যা চায় তা হতে পারে, \ n এবং \ t এর মতো জিনিসের উপর নির্ভর করে।
জেটেরেস

@ জেটেরাস ডানদিকে স্পেস অন্তর্ভুক্ত রয়েছে (অধ্যায় 32) তবে কোনও রিটার্ন এবং ট্যাব নেই
joaquin

হ্যাঁ, কেবল "এটি স্ট্রিংয়ের সাথে সমান" প্রিন্টেবল "সম্পর্কে মন্তব্য করা হলেও সত্য নয়
জেটেরেস

আমি উত্তরটি সম্পাদনা করেছি, ধন্যবাদ! আপনি যদি মনোযোগ সহকারে এটি না পড়েন তবে ওপি প্রশ্নটি বিভ্রান্ত করছে।
joaquin

1

ফ্লুয়েন্ট পাইথন (রামালহো) এর মাধ্যমে আমার পথে কাজ করা - অত্যন্ত প্রস্তাবিত। অধ্যায় 2 দ্বারা অনুপ্রাণিত এক-ইশ-লাইনার সমঝোতার তালিকা করুন:

onlyascii = ''.join([s for s in data if ord(s) < 127])
onlymatch = ''.join([s for s in data if s in
              'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'])

এটি বুলেট পয়েন্টস, ডিগ্রি প্রতীক, কপিরাইট প্রতীক, ইয়েন প্রতীক ইত্যাদির মতো স্ট্যান্ডার্ড ASCII চিহ্নগুলির জন্য অনুমতি দেয় না, এছাড়াও আপনার প্রথম উদাহরণে অপ্রকাশিত নয় এমন বেল যেমন প্রিন্টযোগ্য চিহ্নগুলি অন্তর্ভুক্ত রয়েছে।
শেরিলহোমান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.