আমি কীভাবে ইউটিএফ -8 তে ফার্সি সংখ্যাগুলি ASCII তে ইউরোপীয় অঙ্কগুলিতে রূপান্তর করতে পারি?


16

ফার্সি সংখ্যাগুলিতে, ইউরোপীয় অঙ্কগুলির ۰۱۲۳۴۵۶۷۸۹সমান 0123456789

আমি কীভাবে ফার্সি নম্বর (ইন UTF-8) এএসসিআই তে রূপান্তর করতে পারি ?

উদাহরণস্বরূপ, আমি ۲۱হয়ে উঠতে চাই 21


1
মজার বিষয়, দেখে মনে হচ্ছে এটি echo "۰۱۲۳۴۵۶۷۸۹" | iconv -f UTF-8 -t ascii//TRANSLITহ্যান্ডেল করে না ...
কুসালানন্দ

@ কুসালানন্দ কাজ
করেননি

3
@ কুসালানন্দ: আসলেই কি তা অপ্রত্যাশিত? যেহেতু আমি বুঝতে পেরেছিলাম যে iconvএখানে বিভিন্ন এনকোডিংগুলিতে অক্ষরগুলি মানচিত্র করা ঠিক আছে, তবে এগুলি অক্ষর (পূর্ব আরবি সংখ্যা) যা ASCII তে কোনও সমতুল্য নয়, আপনি কেবল তাদেরকে এ জাতীয় কিছুতে রূপান্তর করতে পারেন তবে এটি কেবল একমুখী।
পিএইচকে

3
ঠিক আছে, আমি কী iconvকরতে সক্ষম এবং কি সক্ষম নয় সে সম্পর্কে পুরোপুরি নিশ্চিত ছিলাম না। আমি আশা করছিলাম যে এই ব্যবহারটি //TRANSLITসাহায্য করবে তবে তা হয়নি।
কুসালানন্দ

1
আপনারও কি অর্ডারটি বিপরীত করা দরকার? আমি জানি যে আরবী সংখ্যাগুলি ডান থেকে বামে সামান্য এন্ডিয়ান লেখা থাকে এবং লাতিন সংখ্যাগুলি বড়-এন্ডিয়ান বাম থেকে ডান হয় (প্রিন্টে বা স্ক্রিনে অনুরূপ, তবে স্মৃতিতে বিপরীত হয়)। ফারসি কি একই রকম?
টবি স্পিড

উত্তর:


6

আমরা পার্সিয়ান সংখ্যাগুলির ইউনিকোড কোড পয়েন্ট ধারাবাহিকভাবে এবং 0 থেকে 9 পর্যন্ত আদেশের বিষয়টি গ্রহণ করতে পারি :

$ printf '%b' '\U06F'{0..9}
۰۱۲۳۴۵۶۷۸۹

এর অর্থ হ'ল শেষ হেক্স অঙ্কটি দশমিক মান:

$ echo $(( $(printf '%d' "'۲") & 0xF ))
2

এটি এই সরল লুপকে রূপান্তর সরঞ্জাম তৈরি করে:

#!/bin/bash
(   ### Use a locale that use UTF-8 to make the script more reliable.
    ### Maybe something like LC_ALL=fa_IR.UTF-8 for you?.
    LC_ALL=en_US.UTF-8
    a="$1"
    while (( ${#a} > 0 )); do
        # extract the last hex digit from the UNICODE code point
        # of the first character in the string "$a":
        printf '%d' $(( $(printf '%d' "'$a") & 15 ))
        a=${a#?}    ## Remove one character from $a
    done
)
echo

এটি হিসাবে ব্যবহার:

$ sefr.sh ۰۱۲۳۴۵۶۷۸۹
0123456789

$ sefr.sh ۲۰۱
201

$ sefr.sh ۲۱
21

নোট করুন যে এই কোডটি আরবী এবং লাতিন সংখ্যাকে রূপান্তর করতে পারে (এমনকি যদি মিশ্রও হয়):

$ sefr.sh ۴4٤۵5٥۶6٦۷7٧۸8٨۹9٩
444555666777888999

$ sefr.sh ٤٧0٠٦7١٣3٥۶٦۷
4700671335667

খুব ধন্যবাদ, এটি খুব সুন্দর সমাধান ,,, এবং আমার কাছে প্রশ্ন আছে, এই কমান্ডে প্রিন্টফ '% d' '"۰' কেন ডাবল কোটেশন ব্যবহার করবেন?
বারপাবাবা

@Babyy এটি একটি ডবল উদ্ধৃতি নয়, এটা একটি উপায় দিতে printf, একটি আর্গুমেন্ট একটি একক উদ্ধৃতি দিয়ে শুরু হয়: । এটি হিসাবে লেখা যেতে পারে '"۰'। কারণটি হ'ল প্রিন্টফ ইউনিকোড কোড পয়েন্ট দিবে যদি একটি যুক্তি 'বা একটি ডাবল উদ্ধৃতি দিয়ে যুক্তি শুরু হয় "এই লিঙ্কটির সামান্য আগে অনুসন্ধান করুন "যদি নেতৃস্থানীয় চরিত্রটি একক-উদ্ধৃতি বা ডাবল-উদ্ধৃতি হয়"

@ বাবি কোডটি পার্সিয়ান, আরবি এবং লাতিনে রূপান্তর করতে প্রসারিত হয়েছে (এমনকি যদি মিশ্রও হয়)।

27

যেহেতু এটি সংখ্যার একটি নির্দিষ্ট সেট, তাই আপনি এটি হাতে করে করতে পারেন:

$ echo ۲۱ | LC_ALL=en_US.UTF-8 sed -e 'y/۰۱۲۳۴۵۶۷۸۹/0123456789/'
21

(বা ব্যবহার করছেন tr, তবে এখনও জিএনইউ ট্রির নয় )

আপনার অক্ষর সেটটি সনাক্ত en_US.utf8করার জন্য আপনার লোকেলটি সেট করা (অথবা স্থানীয় বর্ণগুলির সাথে সর্বাধিক অক্ষরগুলি সেট করা ভাল) issed

সহ perl:

$ echo "۲۱" |
  perl -CS -MUnicode::UCD=num -MUnicode::Normalize -lne 'print num(NFKD($_))'
21

প্রয়োজনীয় সেট LC_ALLকরা প্রয়োজন যাতে প্রতিটি এককোডে অক্ষরগুলিও ঠিক তাই বলে বিবেচিত হবে sed?
পিএইচকে

@ পিএফকে: হ্যাঁ, আপডেট করা দেখুন।
cuonglm

সবকিছু কেন একটি সেড স্ক্রিপ্ট হতে হবে? আমরা কি trএই সঠিক উদ্দেশ্যে আবিষ্কার করিনি ?
কেভিন

3
@ কেভিন trকীভাবে এটি সর্বত্র কাজ করে না সে সম্পর্কিত অন্যান্য উত্তর দেখুন See এছাড়াও মনে রাখবেন যে কিছু সরঞ্জাম বাইটগুলি নিয়ে কাজ করার জন্য অনুকূলিত হয়েছে যখন অন্যরা অক্ষরগুলি নিয়ে কাজ করার জন্য, ইউনিকোডের সাথে (বিশেষত ইউটিএফ -8) এটি একটি বিশাল পার্থক্য করে।
পিএইচকে

এটি OS X 10.10.5 / GNU ব্যাশ 4.3 এ আমার জন্য কাজ করে না। আশ্চর্যরকমভাবে পর্যাপ্তরূপে আমাকে এর সুস্পষ্ট সেটিংটি সরিয়ে ফেলতে হবেLC_ALLLC_ALLআমার পরিবেশেও LANGসেট করা নেই (তবে সেট করা আছে en_GB.UTF-8)। উপরের কোডটি সহ, আমি ত্রুটিটি পেয়েছি "সেড: 1:" y / ۰۱۲۳۴۵۶۷۸۹ / ... ": রূপান্তর স্ট্রিংগুলি একই দৈর্ঘ্য নয়" are
কনরাড রুডলফ

15

পাইথনের জন্য একটি unidecodeলাইব্রেরি রয়েছে যা সাধারণভাবে এই ধরণের রূপান্তরগুলি পরিচালনা করে: https://pypi.python.org/pypi/Unidecode

পাইথন 2 এ:

>>> from unidecode import unidecode
>>> unidecode(u"۰۱۲۳۴۵۶۷۸۹")
'0123456789'

পাইথন 3 এ:

>>> from unidecode import unidecode
>>> unidecode("۰۱۲۳۴۵۶۷۸۹")
'0123456789'

Https://stackoverflow.com/q/8087381/2261442 এ SO থ্রেড সম্পর্কিত হতে পারে।

/ সম্পাদনা: ওয়ান্ডার নওতা মন্তব্যগুলিতে যেমন উল্লেখ করেছেন এবং ইউনিকিডকোড পৃষ্ঠায় উল্লিখিত হয়েছে তেমন একটি শেল সংস্করণও রয়েছে unidecode( /usr/local/bin/যদি এটি ইনস্টল করা থাকে তবে এর নীচে pip):

$ echo '۰۱۲۳۴۵۶۷۸۹' | unidecode
0123456789

2
ইউনিিডকোড গ্রন্থাগারটি (আশ্চর্যজনকভাবে) নামে একটি ইউটিলিটিও পাঠায় unidecodeযা আপনার পাইথন 3 স্নিপেটের মতো করে। শুধু echo '۰۱۲۳۴۵۶۷۸۹' | unidecodeকাজ করা উচিত।
ঘোরাঘুরি নওতা

@ ওয়ান্ডার - পাইথন-ইউনিডিকোডের ডেবিয়ান প্যাকেজটি ইউটিলিটি প্রোগ্রামটি পাঠায় না, সুতরাং এই জাতীয় প্ল্যাটফর্মগুলিতে দীর্ঘ ফর্মটি প্রয়োজনীয় হতে পারে (উত্স থেকে উত্স টারবালটিতে আমি একটিও পাইনি, সম্ভবত প্রোগ্রামটি কিছু যোগ করেছে আপনার বিতরণ?)
টবি স্পিড

@ টবিস্পাইট যদি আপনি এটি ব্যবহার করে pipএটি ইনস্টল করেন।
পিএইচকে

@TobySpeight উপযোগ হিসাবে মূল প্রজেক্টের tarball রূপে হয় unidecode/util.py- অদ্ভুত ডেবিয়ান এটা অন্তর্ভুক্ত নয় যে। : (সম্পাদনা আহ, রহস্য সমাধান ডেবিয়ান প্যাকেজ তারিখ এবং উপযোগ চেয়ে পুরোনো হয়ে গেছে।।)
Wander Nauta

7

খাঁটি বাশ সংস্করণ:

#!/bin/bash

number="$1"

number=${number//۱/1}
number=${number//۲/2}
number=${number//۳/3}
number=${number//۴/4}
number=${number//۵/5}
number=${number//۶/6}
number=${number//۷/7}
number=${number//۸/8}
number=${number//۹/9}
number=${number//۰/0}

echo "Result is $number"

আমার জেন্টু মেশিনে পরীক্ষা করেছে এবং এটি কাজ করে।

./convert ۱۳۲
Result is 132

একটি লুপ হিসাবে সম্পন্ন হয়েছে, রূপান্তর করতে অক্ষরের তালিকা দেওয়া হয়েছে (0 থেকে 9 পর্যন্ত):

#!/bin/bash
conv() ( LC_ALL=en_US.UTF-8
         local n="$2"
         for ((i=0;i<${#1};i++)); do
              n=${n//"${1:i:1}"/"$i"}
         done
         printf '%s\n' "$n"
       )

conv "۰۱۲۳۴۵۶۷۸۹" "$1"

এবং হিসাবে ব্যবহৃত:

$ convert ۱۳۲
132

আর একটি (বরং ওভারকিল) উপায় grep:

#!/bin/bash

nums=$(echo "$1" | grep -o .)
result=()

for i in $nums
do
    case $i in
        ۱)
            result+=1
            ;;
        ۲)
            result+=2
            ;;
        ۳)
            result+=3
            ;;
        ۴)
            result+=4
            ;;
        ۵)
            result+=5
            ;;
        ۶)
            result+=6
            ;;
        ۷)
            result+=7
            ;;
        ۸)
            result+=8
            ;;
        ۹)
            result+=9
            ;;
        ۰)
            result+=0
            ;;
    esac
done
echo "Result is $result"

1
বিশুদ্ধ ব্যাশ, জন্য ছাড়া grep। আসলে, আমি সেই লাইনটি বুঝতে পারি না বা কেন আপনি সেট করেন না result=0$1ফারসি সংখ্যা ব্যতীত অন্য কিছু রয়েছে সে ক্ষেত্রে আপনি কি অতিরিক্ত সতর্ক হন ?
কুসালানন্দ

@ কুসালানন্দ line লাইনটি ফার্সি অঙ্কগুলি সংখ্যায় পড়ে reads এটি লুপ-সক্ষম করে তোলে।
coffeMug

1
দশ সহজ বদল দ্রুততর পারতাম ... number=${number//۱/1}ইত্যাদি, এবং এড়ানো হবে echoএবং grep
কুসালানন্দ

1
পছন্দ করুন এটা পরিবর্তন। এখন খাঁটি বাশ! ;-)
coffeMug

@coffeMug: 13 132 ন 123: ডি
বারপابাবা

3

যেহেতু iconvএটি আঁকড়ে উঠতে পারে না বলে কল করার পরবর্তী পোর্টটি trইউটিলিটিটি ব্যবহার করা হবে :

$ echo "۲۱" | tr '۰۱۲۳۴۵۶۷۸۹' '0123456789'
21

tr অক্ষরের একটি সেটকে অন্যটিতে অনুবাদ করে, তাই আমরা কেবল এটিকে ফার্সি অঙ্কগুলির সেটটি লাতিন অঙ্কের সেটটিতে অনুবাদ করতে বলি।

সম্পাদনা : ব্যবহারকারী হিসাবে @ কুওগলম পয়েন্ট। এটির জন্য নন-জিএনইউ প্রয়োজন tr, উদাহরণস্বরূপ trম্যাকের জন্য এবং এটির জন্য এটি $LC_CTYPEসেট করাও দরকার en_US.UTF-8


2
নোট করুন যে এটি GNU tr এর সাথে কাজ করবে না, যা মাল্টি-বাইট অক্ষর সমর্থন করে না।
cuonglm

1
আহারে. বোকা জিএনইউ। ;-)
কুসালানন্দ

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