পাইথন ইউনিকোড স্ট্রিংয়ে অ্যাকসেন্টগুলি সরানোর সর্বোত্তম উপায় কী?


503

পাইথনে আমার একটি ইউনিকোড স্ট্রিং রয়েছে এবং আমি সমস্ত উচ্চারণ (ডায়াক্রিটিক্স) মুছে ফেলতে চাই।

আমি জাভাতে এটি করার একটি দুর্দান্ত উপায় ওয়েবে পেয়েছি:

  1. ইউনিকোড স্ট্রিংটিকে তার দীর্ঘ স্বাভাবিক আকারে রূপান্তর করুন (অক্ষর এবং ডায়াক্রিটিক্সের জন্য পৃথক চরিত্র সহ)
  2. যার ইউনিকোড টাইপ "ডায়াক্রিটিক" সমস্ত অক্ষর মুছে ফেলুন।

আমার কি পাইকইউয়ের মতো লাইব্রেরি ইনস্টল করার দরকার আছে বা কেবল পাইথন স্ট্যান্ডার্ড লাইব্রেরি দিয়ে এটি সম্ভব? এবং অজগর 3 সম্পর্কে কী?

গুরুত্বপূর্ণ দ্রষ্টব্য: আমি উচ্চারণযুক্ত অক্ষরগুলি থেকে তাদের অ-উচ্চারণযুক্ত অংশে স্পষ্টভাবে ম্যাপিং সহ কোড এড়াতে চাই।

উত্তর:


446

ইউনিডিকোড এটির সঠিক উত্তর। এটি যে কোনও ইউনিকোড স্ট্রিংকে আসকি পাঠ্যে নিকটতম সম্ভাব্য উপস্থাপনায় রূপান্তরিত করে।

উদাহরণ:

accented_string = u'Málaga'
# accented_string is of type 'unicode'
import unidecode
unaccented_string = unidecode.unidecode(accented_string)
# unaccented_string contains 'Malaga'and is of type 'str'

67
চাইনিজদের সাথে ভালভাবে কাজ করার কথা মনে হচ্ছে তবে ফরাসি নাম "ফ্রেঞ্চোইস" এর রূপান্তর দুর্ভাগ্যবশত "ফ্রান্সআসোইস" দেয়, যা খুব বেশি প্রাকৃতিক "ফ্রেঞ্চোইস" এর তুলনায় খুব ভাল নয়।
এরিক হে লেবিগোট

10
আপনি কী অর্জন করতে চাইছেন তা নির্ভর করে উদাহরণস্বরূপ আমি এখনই একটি অনুসন্ধান করছি, এবং আমি গ্রীক / রাশিয়ান / চীনা অনুবাদ করতে চাই না, আমি কেবল "ą / ę / ś / ć" "এ / ই / এস / সি" দিয়ে প্রতিস্থাপন করতে চাই
কলিঙ্কো

58
আপনি যদি ইউনিকোড বস্তুগুলিতে এটি পাস করেন তবে @ ইওল ​​ইউনিিডকোড "ফ্রান্সোইস" এর মতো স্ট্রিংয়ের জন্য দুর্দান্ত কাজ করে। দেখে মনে হচ্ছে আপনি একটি সরল বাইট স্ট্রিং দিয়ে চেষ্টা করেছেন tried
কার্ল বার্টেল

26
নোট করুন যে ইউনিিডকোড> = 0.04.10 (ডিসেম্বর 2012) জিপিএল। পূর্ববর্তী সংস্করণগুলি ব্যবহার করুন বা যদি আপনার আরও অনুমতিপ্রাপ্ত লাইসেন্স প্রয়োজন হয় এবং কিছুটা খারাপ বাস্তবায়ন করতে পারেন তবে github.com/kmike/text-unidecode দেখুন।
মিখাইল কোরোভভ

10
unidecode°সঙ্গে প্রতিস্থাপন deg। এটি কেবল উচ্চারণগুলি সরানোর চেয়ে আরও বেশি কিছু করে।
এরিক ডুমিনিল

273

এটি সম্পর্কে:

import unicodedata
def strip_accents(s):
   return ''.join(c for c in unicodedata.normalize('NFD', s)
                  if unicodedata.category(c) != 'Mn')

এটি গ্রীক বর্ণগুলিতেও কাজ করে:

>>> strip_accents(u"A \u00c0 \u0394 \u038E")
u'A A \u0394 \u03a5'
>>> 

চরিত্র বিভাগ "Mn" ঘোরা জন্য Nonspacing_Markযা MiniQuark এর উত্তরে unicodedata.combining অনুরূপ, (আমি unicodedata.combining মনে করা হয়নি, কিন্তু এটা সম্ভবত ভাল সমাধান পাওয়া যাবে কারণ এটির আরও বেশি স্পষ্ট এর)।

এবং মনে রাখবেন, এই হেরফেরগুলি পাঠ্যের অর্থকে উল্লেখযোগ্যভাবে পরিবর্তন করতে পারে। অ্যাকসেন্টস, উমলৌত ইত্যাদি "সজ্জা" নয়।


6
এগুলি অক্ষর রচিত নয়, দুর্ভাগ্যক্রমে - যদিও "ł" এর নাম দেওয়া হয়েছে "LATIN SMALL LETTER L WITH STROKE"! আপনাকে পার্সিং দিয়ে গেমস খেলতে হবে unicodedata.name, অথবা ভেঙে দেখতে হবে এবং একই রকমের টেবিল ব্যবহার করতে হবে - যা আপনাকে যেভাবেই গ্রীক অক্ষরের জন্য প্রয়োজন হবে (Α কেবল "গ্রিক ক্যাপিটাল লেটার আলফা")।
অ্যালেক্সিস

2
@ কান্দি, আমি ভয় করি যে আপনি কোন পয়েন্টটি বানাতে চান তা অনুমান করতে পারছি না। ইমেল এক্সচেঞ্জটি আমি উপরে যা লিখেছি তা প্রতিফলিত করে: যেহেতু "ł" বর্ণটি উচ্চারণকৃত চিঠি নয় (এবং এটি ইউনিকোডের মান হিসাবে বিবেচিত হয় না), এতে ক্ষয় হয় না dec
অ্যালেক্সিস

2
@ অ্যালেক্সিস (দেরীতে ফলোআপ): এটি গ্রিকের পক্ষেও পুরোপুরি ভাল কাজ করে - যেমন। "ড্যাসিয়া এবং ভারিয়ার সাথে গ্রেট ক্যাপিটাল লেটার আলফা" প্রত্যাশার মতোই "গ্রেট ক্যাপিটাল লেটার আলফা" তে সাধারণীকরণ করা হয়েছে। যদি না আপনি উল্লেখ করা হয় লিপ্যন্তর , যা হিসাবে "সরানোর কথা" একই নয় ... (যেমন "α" → "একটি"।)
lenz

@ এলেনজ, আমি গ্রীক থেকে অ্যাকসেন্টগুলি সরিয়ে ফেলার কথা বলছিলাম না, তবে এলো "স্ট্রোক" সম্পর্কে। যেহেতু এটি ডায়াক্রিটিক নয়, তাই এটি প্লেইন এলে পরিবর্তন করা গ্রীক আলফাকে পরিবর্তনের সমান A। যদি না চান তবে এটি করবেন না, তবে উভয় ক্ষেত্রেই আপনি ল্যাটিন (কাছাকাছি) চেহারা-সমানকে প্রতিস্থাপন করছেন।
Alexis

বেশিরভাগই দুর্দান্ত কাজ করে :) তবে এটি উদাহরণ হিসাবে ßআসকি রূপান্তর করে না ss। আমি এখনও unidecodeদুর্ঘটনা এড়াতে ব্যবহার করতে হবে।
আর্ট

145

আমি ওয়েবে এই উত্তরটি পেয়েছি:

import unicodedata

def remove_accents(input_str):
    nfkd_form = unicodedata.normalize('NFKD', input_str)
    only_ascii = nfkd_form.encode('ASCII', 'ignore')
    return only_ascii

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

সম্পাদনা করুন : এটি কৌশলটি করে:

import unicodedata

def remove_accents(input_str):
    nfkd_form = unicodedata.normalize('NFKD', input_str)
    return u"".join([c for c in nfkd_form if not unicodedata.combining(c)])

unicodedata.combining(c)cপূর্ববর্তী চরিত্রটির সাথে যদি চরিত্রটি একত্রিত করা যায় তবে সত্যটি ফিরে আসবে , এটি মূলত যদি এটি ডায়াস্রিটিক হয়।

সম্পাদনা 2 : remove_accentsএকটি ইউনিকোড স্ট্রিং প্রত্যাশা করে , বাইট স্ট্রিং নয়। আপনার যদি বাইট স্ট্রিং থাকে, তবে আপনাকে অবশ্যই এটির মতো একটি ইউনিকোড স্ট্রিংয়ে ডিকোড করতে হবে:

encoding = "utf-8" # or iso-8859-15, or cp1252, or whatever encoding you use
byte_string = b"café"  # or simply "café" before python 3.
unicode_string = byte_string.decode(encoding)

5
আমাকে ইউনিকোডে 'utf8' যুক্ত করতে হয়েছিল:nkfd_form = unicodedata.normalize('NFKD', unicode(input_str, 'utf8'))
জাব্বা

@ জাবা: , 'utf8'যদি আপনি টার্মিনালে ইনপুট পরীক্ষা করে থাকেন (যা ডিফল্টরূপে ইউনিকোড ব্যবহার করে না) একটি "সুরক্ষা নেট" দরকার। কিন্তু সাধারণত আপনাকে না আছে এটি যোগ করতে, যেহেতু আপনি কথা তারপর সরানোর করছি input_strখুব ইতিমধ্যে UTF8 হতে পারে। যদিও এটি নিরাপদ থাকতে আঘাত করে না।
MestreLion

1
@ আরবিপি: আপনার remove_accentsনিয়মিত স্ট্রিংয়ের পরিবর্তে ইউনিকোড স্ট্রিংটি পাস করতে হবে ("instead" এর পরিবর্তে আপনি "" ")। আপনি একটি নিয়মিত স্ট্রিং এতে পাস করেছেন remove_accents, সুতরাং আপনার স্ট্রিংটিকে ইউনিকোড স্ট্রিংয়ে রূপান্তর করার চেষ্টা করার সময়, ডিফল্ট asciiএনকোডিং ব্যবহৃত হয়েছিল। এই এনকোডিংটি এমন কোনও বাইটকে সমর্থন করে না যার মান> 127। আপনি যখন আপনার শেলটিতে "é" টাইপ করেছেন, আপনার ওএস এটিকে এনকোড করেছে, সম্ভবত ইউটিএফ -8 বা কিছু উইন্ডোজ কোড পৃষ্ঠা এনকোডিং সহ এবং এতে বাইটস> 127 অন্তর্ভুক্ত রয়েছে। আমি ইউনিকোডে রূপান্তরটি সরাতে আমার ফাংশনটি পরিবর্তন করব: অ-ইউনিকোড স্ট্রিংটি পাস করা হলে এটি আরও স্পষ্টভাবে বোমা ফেলবে।
MiniQuark

1
@ মিনিকিয়ার্ক যা পুরোপুরি কাজ করেছে >>> অপসারণ_অ্যাকসেন্টস (ইউনিকোড ('é'))
আরবিপি

1
এই উত্তরটি আমাকে একটি বড় ডেটা সেটে সেরা ফলাফল দিয়েছে, কেবলমাত্র ব্যতিক্রম "ð" - ইউনিকোডেটা এটি স্পর্শ করবে না!
s29

43

প্রকৃতপক্ষে আমি প্রজেক্টের সামঞ্জস্যপূর্ণ পাইথন ২. 2., ২. on এবং ৩.৪ নিয়ে কাজ করি এবং আমাকে ফ্রি ব্যবহারকারীর এন্ট্রি থেকে আইডি তৈরি করতে হয়।

আপনাকে ধন্যবাদ, আমি এই ফাংশনটি তৈরি করেছি যা আশ্চর্য কাজ করে।

import re
import unicodedata

def strip_accents(text):
    """
    Strip accents from input String.

    :param text: The input string.
    :type text: String.

    :returns: The processed String.
    :rtype: String.
    """
    try:
        text = unicode(text, 'utf-8')
    except (TypeError, NameError): # unicode is a default on python 3 
        pass
    text = unicodedata.normalize('NFD', text)
    text = text.encode('ascii', 'ignore')
    text = text.decode("utf-8")
    return str(text)

def text_to_id(text):
    """
    Convert input text to id.

    :param text: The input string.
    :type text: String.

    :returns: The processed String.
    :rtype: String.
    """
    text = strip_accents(text.lower())
    text = re.sub('[ ]+', '_', text)
    text = re.sub('[^0-9a-zA-Z_-]', '', text)
    return text

ফলাফল:

text_to_id("Montréal, über, 12.89, Mère, Françoise, noël, 889")
>>> 'montreal_uber_1289_mere_francoise_noel_889'

2
পাই 2.7 দিয়ে ইতিমধ্যে ইউনিকোড স্ট্রিং ত্রুটিগুলি পাস করছে text = unicode(text, 'utf-8')। এটির জন্য একটি কর্মসংস্থান ছিলexcept TypeError: pass
ড্যানিয়েল রেইস

খুব আওয়াজ! আমার ক্ষেত্রে কাজ করেছে। উমা সেলিও ডি পোয়েশিয়া ব্রাসিলিরা প্যারা ডেসেনভলভার একটি ক্যাপাসিডে দে এস্কুটা ডস অ্যালুনস আইডিয়োমা পোর্টুগিজ।
হারুন

23

এটি কেবল উচ্চারণকেই পরিচালনা করে না, "স্ট্রোক" (যেমন ø ইত্যাদি):

import unicodedata as ud

def rmdiacritics(char):
    '''
    Return the base character of char, by "removing" any
    diacritics like accents or curls and strokes and the like.
    '''
    desc = ud.name(char)
    cutoff = desc.find(' WITH ')
    if cutoff != -1:
        desc = desc[:cutoff]
        try:
            char = ud.lookup(desc)
        except KeyError:
            pass  # removing "WITH ..." produced an invalid name
    return char

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

এখনও এমন বিশেষ অক্ষর রয়েছে যা এগুলি দ্বারা পরিচালিত হয় না, যেমন ঘুরিয়ে দেওয়া এবং উল্টানো অক্ষর, কারণ তাদের ইউনিকোড নামটিতে 'WITH' নেই। এটি যাইহোক আপনি কী করতে চান তার উপর নির্ভর করে। অভিধানের বাছাইয়ের ক্রম অর্জনের জন্য আমার মাঝে মাঝে অ্যাকসেন্ট স্ট্রিপিংয়ের প্রয়োজন হয়।

সম্পাদনা দ্রষ্টব্য:

মন্তব্যগুলি থেকে অন্তর্ভুক্ত পরামর্শ (হ্যান্ডলিং ত্রুটির ত্রুটি, পাইথন -3 কোড)।


8
নতুন প্রতীকটি উপস্থিত না থাকলে আপনার ব্যতিক্রম ধরা উচিত। উদাহরণস্বরূপ ভার্চিকাল পূরণ S সহ স্কোয়ার রয়েছে, তবে কোনও স্কোয়ার নেই। (এই কোডটি বৃষ্টিপাতের সাথে UMBRELLA ☔ কে UMBRELLA ☔ এ রূপান্তর করে mention
janek37

উপলব্ধ অক্ষরগুলির শব্দার্থক বর্ণনাকে জোড় করে দেখাতে এটি মার্জিত দেখাচ্ছে। unicodeপাইথন 3 সহ আমাদের সেখানে কি আসলেই ফাংশন কলটি দরকার ? আমি মনে করি findউপরের মন্তব্যে উল্লিখিত সমস্ত ঝামেলা এড়ানোর পরিবর্তে একটি শক্ত রেজেক্সটি এড়াতে পারে এবং মেমোজাইজেশন যখন একটি গুরুত্বপূর্ণ কোড পাথ হবে তখন মেমোয়েজেশন কার্য সম্পাদনে সহায়তা করবে।
ম্যাটানস্টার

1
@ ম্যান্টাস্টার না, পাইথন -২ যুগের এটি একটি পুরানো উত্তর; unicodetypecast আর পাইথন 3 উপযুক্ত যাই হোক, আমার অভিজ্ঞতা আছে এই সমস্যার কোন সার্বজনীন, মার্জিত সমাধান। অ্যাপ্লিকেশন উপর নির্ভর করে, যে কোনও পদ্ধতির তার উপকারিতা এবং বিপরীতে রয়েছে। গুণমান-সমৃদ্ধ সরঞ্জামগুলি unidecodeহ্যান্ড ক্র্যাফ্টেড টেবিলের উপর ভিত্তি করে। কিছু সংস্থান (টেবিল, অ্যালগরিদম) ইউনিকোড দ্বারা সরবরাহ করা হয়, যেমন। কোলেশন জন্য।
লেনজ

1
আমি কেবল পুনরাবৃত্তি করছি, যা উপরে রয়েছে (পিআই 3): 1) ইউনিকোড (চর) -> চর 2) চেষ্টা করুন: কীয়ারর ব্যতীত ud.lookup (desc) ফিরিয়ে দিন: ফেরত চর
মিরেক

@ মিরেক আপনি ঠিক বলেছেন: যেহেতু এই থ্রেডটি এত জনপ্রিয়, এই উত্তরটি কিছু আপডেট / উন্নতির দাবিদার। আমি এটি সম্পাদনা করেছি।
লেনজ

15

@ MiniQuark এর উত্তরের প্রতিক্রিয়া:

আমি একটি সিএসভি ফাইলে পড়ার চেষ্টা করছিলাম যা অর্ধ-ফরাসি (অ্যাকসেন্ট সহ) এবং কিছু স্ট্রিং যা শেষ পর্যন্ত পূর্ণসংখ্যার এবং ভাসমান হয়ে উঠবে। পরীক্ষা হিসাবে, আমি এমন একটি test.txtফাইল তৈরি করেছি যা দেখতে এরকম দেখাচ্ছে:

মন্ট্রিয়াল, ওবার, 12.89, মেরে, ফ্রান্সেস, নোল, 889

আমাকে লাইনগুলি অন্তর্ভুক্ত করতে হয়েছিল 2এবং 3এটি কাজ করতে (যা আমি পাইথনের টিকিটে পেয়েছি) পাশাপাশি @ জব্বার মন্তব্য অন্তর্ভুক্ত করেছিলাম:

import sys 
reload(sys) 
sys.setdefaultencoding("utf-8")
import csv
import unicodedata

def remove_accents(input_str):
    nkfd_form = unicodedata.normalize('NFKD', unicode(input_str))
    return u"".join([c for c in nkfd_form if not unicodedata.combining(c)])

with open('test.txt') as f:
    read = csv.reader(f)
    for row in read:
        for element in row:
            print remove_accents(element)

ফলাফল:

Montreal
uber
12.89
Mere
Francoise
noel
889

(দ্রষ্টব্য: আমি ম্যাক ওএস এক্স ১০.৮.৪ এ রয়েছি এবং পাইথন ২.7.৩ ব্যবহার করছি)


1
remove_accentsএকটি ইউনিকোড স্ট্রিং থেকে অ্যাকসেন্টগুলি সরাতে বোঝানো হয়েছিল। যদি এটি একটি বাইট স্ট্রিং উত্তীর্ণ হয়, এটি এটি একটি ইউনিকোড স্ট্রিংয়ের সাথে রূপান্তরিত করার চেষ্টা করে unicode(input_str)। এটি পাইথনের ডিফল্ট এনকোডিংটি ব্যবহার করে যা "এসকিআই"। যেহেতু আপনার ফাইলটি ইউটিএফ -8 এর সাথে এনকোড রয়েছে তাই এটি ব্যর্থ হবে। 2 এবং 3 লাইনগুলি পাইথনের ডিফল্ট এনকোডিংটি ইউটিএফ -8 এ পরিবর্তন করে, সুতরাং এটি কার্যকর হয়, যেমন আপনি খুঁজে পেয়েছেন। আরেকটি বিকল্প পাস হয় remove_accentsএকটি ইউনিকোড: STRING অপসারণ লাইন 2 এবং 3, এবং শেষ লাইনে প্রতিস্থাপন elementদ্বারা element.decode("utf-8")। আমি পরীক্ষা করেছি: এটি কাজ করে। এই উত্তরটি পরিষ্কার করার জন্য আমি আমার উত্তর আপডেট করব।
MiniQuark

সুন্দর সম্পাদনা, ভাল পয়েন্ট। (অন্য একটি নোটের উপরে: আমি যে সত্যিকারের সমস্যাটি উপলব্ধি করেছি তা হ'ল আমার ডেটা ফাইলটি দৃশ্যত এনকোড করা আছে iso-8859-1, যা দুর্ভাগ্যক্রমে আমি এই ফাংশনটির সাথে কাজ করতে পারব না!)
এসেইগ্রাম

এসিগ্রাম: কেবলমাত্র "utf-8" কে "iso-8859-1" এর সাথে প্রতিস্থাপন করুন এবং এটির কাজ করা উচিত। আপনি যদি উইন্ডোতে থাকেন তবে আপনার পরিবর্তে সম্ভবত "cp1252" ব্যবহার করা উচিত।
MiniQuark

বিটিডাব্লু, reload(sys); sys.setdefaultencoding("utf-8")একটি সন্দেহজনক হ্যাক যা কখনও কখনও উইন্ডোজ সিস্টেমগুলির জন্য প্রস্তাবিত হয়; দেখাবিশদ stackoverflow.com/questions/28657010/… দেখুন।
পিএম 2Ring

14

gensim.utils.deaccent (পাঠ্য) Gensim থেকে - মানুষের জন্য বিষয় মডেলিং :

'Sef chomutovskych komunistu dostal postou bily prasek'

আরেকটি সমাধান হ'ল ইউনিিডিকোড

নোট যে সঙ্গে পরামর্শ সমাধান unicodedata সাধারণত (যেমন এটি সক্রিয় শুধুমাত্র কিছু চরিত্র কথা সরিয়ে ফেলা 'ł'মধ্যে ''বরং মধ্যে পরিবর্তে, 'l')।


1
deaccentএখনও łপরিবর্তে দেয় l
l:13lak

আপনাকে ইনস্টল করতে হবে না NumPyএবং SciPyঅ্যাকসেন্টগুলি সরিয়ে ফেলতে হবে না।
নুনো আন্দ্রে

জিনসিম রেফারেন্সের জন্য ধন্যবাদ! এটি ইউনিিডকোডের সাথে কীভাবে তুলনা করে (গতি বা নির্ভুলতার সাথে)?
এটিয়েন কিন্তজলার

3

কিছু ভাষার উচ্চারণ নির্দিষ্ট করার জন্য ভাষার বর্ণ এবং অ্যাকসেন্ট ডায়াক্রিটিক্স হিসাবে ডায়াক্রিটিক্সের সমন্বয় রয়েছে।

আমি মনে করি আপনি কোন ডায়াবেটিকগুলি স্ট্রিপ করতে চান তা স্পষ্টভাবে নির্দিষ্ট করে দেওয়া আরও নিরাপদ:

def strip_accents(string, accents=('COMBINING ACUTE ACCENT', 'COMBINING GRAVE ACCENT', 'COMBINING TILDE')):
    accents = set(map(unicodedata.lookup, accents))
    chars = [c for c in unicodedata.normalize('NFD', string) if c not in accents]
    return unicodedata.normalize('NFC', ''.join(chars))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.