How to Convert Persian Digits in variable to English Digits Using Culture?
Asked Answered
J

18

50

I want to change persian numbers which are saved in variable like this :

string Value="۱۰۳۶۷۵۱"; 

to

string Value="1036751";

How can I use easy way like culture info to do this please?

my sample code is:

List<string> NERKHCOlist = new List<string>();
NERKHCOlist = ScrappingFunction(NERKHCO, NERKHCOlist);
int NERKHCO_Price = int.Parse(NERKHCOlist[0]);//NERKHCOlist[0]=۱۰۳۶۷۵۱ 

<= So it can not Parsed it to int
And This is in my function which retun a list with persian digits inside list items

protected List<string> ScrappingFunction(string SiteAddress, List<string> NodesList)
{    
    string Price = "null";
    List<string> Targets = new List<string>();
    foreach (var path in NodesList)
    {
        HtmlNode node = document.DocumentNode.SelectSingleNode(path.ToString());//recognizing Target Node
        Price = node.InnerHtml;//put text of target node in variable(PERSIAN DIGITS)
        Targets.Add(Price);
    }
    return Targets;
}
Jig answered 20/8, 2013 at 16:56 Comment(1)
Do you mean Scrapping or Scraping?Mel
M
30

I suggest two approaches to handle this issue(I Create an extension method for each of them):

1.foreach and replace

public static class MyExtensions
{
     public static string PersianToEnglish(this string persianStr)
     {
            Dictionary<char, char> LettersDictionary = new Dictionary<char, char>
            {
                ['۰'] = '0',['۱'] = '1',['۲'] = '2',['۳'] = '3',['۴'] = '4',['۵'] = '5',['۶'] = '6',['۷'] = '7',['۸'] = '8',['۹'] = '9'
            };
            foreach (var item in persianStr)
            {
                persianStr = persianStr.Replace(item, LettersDictionary[item]);
            }
            return persianStr;
     }
}

2.Dictionary.Aggregate

public static class MyExtensions
{
      public static string PersianToEnglish(this string persianStr)
      {
            Dictionary<string, string> LettersDictionary = new Dictionary<string, string>
            {
                ["۰"] = "0",["۱"] = "1",["۲"] = "2",["۳"] = "3",["۴"] = "4",["۵"] = "5",["۶"] = "6",["۷"] = "7",["۸"] = "8",["۹"] = "9"
            };
            return LettersDictionary.Aggregate(persianStr, (current, item) =>
                         current.Replace(item.Key, item.Value));
      }
}

More info about Dictionary.Aggregate: Microsoft

Usage:

string result = "۱۰۳۶۷۵۱".PersianToEnglish();
Marque answered 6/1, 2019 at 19:46 Comment(0)
M
35

Simply Use the code below :

private string changePersianNumbersToEnglish(string input)
{
  string[] persian = new string[10] { "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" };

   for (int j=0; j<persian.Length; j++)
      input = input.Replace(persian[j], j.ToString());

   return input;
 }
Mcdaniel answered 11/12, 2013 at 11:19 Comment(2)
It still returns a Persian string! Any idea?Cormorant
Please change the argument orders in Replace function ;)Horologium
M
30

I suggest two approaches to handle this issue(I Create an extension method for each of them):

1.foreach and replace

public static class MyExtensions
{
     public static string PersianToEnglish(this string persianStr)
     {
            Dictionary<char, char> LettersDictionary = new Dictionary<char, char>
            {
                ['۰'] = '0',['۱'] = '1',['۲'] = '2',['۳'] = '3',['۴'] = '4',['۵'] = '5',['۶'] = '6',['۷'] = '7',['۸'] = '8',['۹'] = '9'
            };
            foreach (var item in persianStr)
            {
                persianStr = persianStr.Replace(item, LettersDictionary[item]);
            }
            return persianStr;
     }
}

2.Dictionary.Aggregate

public static class MyExtensions
{
      public static string PersianToEnglish(this string persianStr)
      {
            Dictionary<string, string> LettersDictionary = new Dictionary<string, string>
            {
                ["۰"] = "0",["۱"] = "1",["۲"] = "2",["۳"] = "3",["۴"] = "4",["۵"] = "5",["۶"] = "6",["۷"] = "7",["۸"] = "8",["۹"] = "9"
            };
            return LettersDictionary.Aggregate(persianStr, (current, item) =>
                         current.Replace(item.Key, item.Value));
      }
}

More info about Dictionary.Aggregate: Microsoft

Usage:

string result = "۱۰۳۶۷۵۱".PersianToEnglish();
Marque answered 6/1, 2019 at 19:46 Comment(0)
C
22

USE Culture To convert the number from any language to any language

Functions:

public static string ConvertDigitChar(this string str, CultureInfo source, CultureInfo destination)
{
    for (int i = 0; i <= 9; i++)
    {
        str = str.Replace(source.NumberFormat.NativeDigits[i], destination.NumberFormat.NativeDigits[i]);
    }
    return str;
}

public static string ConvertDigitChar(this int digit, CultureInfo destination)
{
    string res = digit.ToString();
    for (int i = 0; i <= 9; i++)
    {
        res = res.Replace(i.ToString(), destination.NumberFormat.NativeDigits[i]);
    }
    return res;
}

How to use the functions:

var fa = CultureInfo.GetCultureInfoByIetfLanguageTag("fa");
var en = CultureInfo.GetCultureInfoByIetfLanguageTag("en");
string str = "۰0۱1۲2۳3۴4۵5۶6۷7۸8۹9";
string r1 = str.ConvertDigitChar(en, fa);
string r2 = str.ConvertDigitChar(fa, en);
int i = 123456789;
string r3 = i.ConvertDigitChar(fa);

Result:

r1: "۰۰۱۱۲۲۳۳۴۴۵۵۶۶۷۷۸۸۹۹"

r2: "00112233445566778899"

r3: "۰۱۲۳۴۵۶۷۸۹"

Callen answered 31/8, 2016 at 14:38 Comment(2)
Useful solution, Specially using Culture, Thanks.Millennium
Getting numbers from culture feels more confidence to me :)Whitewash
T
12

I wrote this extension method to convert Arabic and Persian digits in an string to its Latin representation

public static class Extensions
{
    public static string ConvertDigitsToLatin(this string s)
    {
        var sb = new StringBuilder();
        for (int i = 0; i < s.Length; i++)
        {
            switch (s[i])
            {
                    //Persian digits
                case '\u06f0':
                    sb.Append('0');
                    break;
                case '\u06f1':
                    sb.Append('1');
                    break;
                case '\u06f2':
                    sb.Append('2');
                    break;
                case '\u06f3':
                    sb.Append('3');
                    break;
                case '\u06f4':
                    sb.Append('4');
                    break;
                case '\u06f5':
                    sb.Append('5');
                    break;
                case '\u06f6':
                    sb.Append('6');
                    break;
                case '\u06f7':
                    sb.Append('7');
                    break;
                case '\u06f8':
                    sb.Append('8');
                    break;
                case '\u06f9':
                    sb.Append('9');
                    break;

                    //Arabic digits    
                case '\u0660':
                    sb.Append('0');
                    break;
                case '\u0661':
                    sb.Append('1');
                    break;
                case '\u0662':
                    sb.Append('2');
                    break;
                case '\u0663':
                    sb.Append('3');
                    break;
                case '\u0664':
                    sb.Append('4');
                    break;
                case '\u0665':
                    sb.Append('5');
                    break;
                case '\u0666':
                    sb.Append('6');
                    break;
                case '\u0667':
                    sb.Append('7');
                    break;
                case '\u0668':
                    sb.Append('8');
                    break;
                case '\u0669':
                    sb.Append('9');
                    break;
                default:
                    sb.Append(s[i]);
                    break;
            }
        }
        return sb.ToString();
    }
}
Threewheeler answered 6/3, 2015 at 18:34 Comment(1)
This one changes both Arabic and extended Arabic digits.Enjambment
C
11

You need to parse them first, using e.g. Int32.Parse() with the correct cultural specifier. Once you have it as a plain integer, it's simply a matter of calling ToString() on it, again with the correct cultural specifier.

An alternative solution is to walk the string character by character and just replace any character that is a Persian digit with the corresponding (west) arabic numeral. Other characters can then be preserved as-is, if required.

If the string really contains a number, you should go with the integer parsing method. If it is not just a number, but really a phone number, serial number etc, you might need to use the replacing algorithm instead.

Candescent answered 20/8, 2013 at 16:57 Comment(3)
See documentation for Int32.Parse Method (String, IFormatProvider)Increase
I'd go with TryParse though, this is prone to exceptionsIncrease
Parse() won't do so well with phone and serial numbers.Dannettedanni
P
7

You can manually convert them like so

    char[][] numbers = new char[][]
    {
        "0123456789".ToCharArray(),"persian numbers 0-9 here".ToCharArray()
    };
    public void Convert(string problem)
    {
        for (int x = 0; x <= 9; x++)
        {
            problem.Replace(numbers[0][x], numbers[1][x]);
        }
    }

I don't know the persian numbers so you will have to add them into the char array.

Pitch answered 20/8, 2013 at 17:27 Comment(1)
Thanks but as i said i want to use culture infoJig
S
4

there is a simple way to do this

public static string Fa2En(string str)
{
  return str.Replace("۰", "0")
            .Replace("۱", "1")
            .Replace("۲", "2")
            .Replace("۳", "3")
            .Replace("۴", "4")
            .Replace("۵", "5")
            .Replace("۶", "6")
            .Replace("۷", "7")
            .Replace("۸", "8")
            .Replace("۹", "9");
}
Swordtail answered 13/9, 2020 at 17:0 Comment(0)
C
2

use this static class to change normalize number easily:

public static class Numbers
{
    public static string ChangeToEnglishNumber(this string text)
    {
        var englishNumbers = string.Empty;
        for (var i = 0; i < text.Length; i++)
        {
            if(char.IsNumber(text[i])) englishNumbers += char.GetNumericValue(text, i);
            else englishNumbers += text[i];
        }

        return englishNumbers;
    }
}

Sample:

string test = "۱۰۳۶۷۵۱".ChangeToEnglishNumber(); // => 1036751
Campbellite answered 4/10, 2017 at 11:29 Comment(1)
string.Concat(nums.Select(c => char.GetNumericValue(c) < 0 ? c.ToString() : char.GetNumericValue(c).ToString(CultureInfo.InvariantCulture)));Shaving
D
2

The Saeed's Solution is Ok,But For Double Variables you Must Also replace "٫" Character To "." , So You Can Use :

private string ToEnglishNumber(string strNum)
{
string[] pn = { "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹", "٫" };
string[] en = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9","." };
string chash = strNum;
for (int i = 0; i < 11; i++)
    chash = chash.Replace(pn[i], en[i]);
return chash;
}
Dunbar answered 17/12, 2017 at 6:55 Comment(0)
B
2
    public static string ToEnglishNumber(string input)
    {

        var englishnumbers = new Dictionary<string, string>()
        {
            {"۰","0" }, {"۱","1" }, {"۲","2" }, {"۳","3" },{"۴","4" }, {"۵","5" },{"۶","6" }, {"۷","7" },{"۸","8" }, {"۹","9" },
            {"٠","0" }, {"١","1" }, {"٢","2" }, {"٣","3" },{"٤","4" }, {"٥","5" },{"٦","6" }, {"٧","7" },{"٨","8" }, {"٩","9" },

        };

        foreach (var numbers in englishnumbers)
            input = input.Replace(numbers.Key, numbers.Value);

        return input;
    }
Boneblack answered 19/5, 2018 at 4:23 Comment(1)
You can convert both Arabic and Persian Number to English number with this code.Boneblack
G
1

Here my code convert Persian digits in variable to English , By extension method(Can use with dot after your expression)

private static readonly string[] pn = { "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" };
    private static readonly string[] en = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
    public static string ToEnglishNumber(this string strNum)
    {
        string chash = strNum;
        for (int i = 0; i < 10; i++)
            chash = chash.Replace(pn[i], en[i]);
        return chash;
    }
    public static string ToEnglishNumber(this int intNum)
    {
        string chash = intNum.ToString();
        for (int i = 0; i < 10; i++)
            chash = chash.Replace(pn[i], en[i]);
        return chash;
    }

and when you want to use this code have to write : txt1.Value.ToEnglishNumber();

Gladsome answered 24/10, 2017 at 7:30 Comment(0)
R
1
public static string ChangeNumberToEnglishNumber(string value)
    {
        string result=string.Empty;
        foreach (char ch in value)
        {

            try
            {
                double convertedChar = char.GetNumericValue(ch);
                if (convertedChar >= 0 && convertedChar <= 9)
                {
                    result += convertedChar.ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    result += ch;
                }


            }
            catch (Exception e)
            {
                result += ch;
            }

        }

        return result;
    }
Recorder answered 17/7, 2018 at 4:37 Comment(1)
Kindly add some description as well to support your code. Thanks!Parallax
R
1

Useful and concise:

public static class Utility
    {
        // '۰' = 1632
        // '0' = 48
        // ------------
        //  1632  => '۰'
        //- 1584
        //--------
        //   48   => '0'
        public static string GetEnglish(this string input)
        {
            char[] persianDigitsAscii = input.ToCharArray(); //{ 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641 };
            string output = "";
            for (int k = 0; k < persianDigitsAscii.Length; k++)
            {
                persianDigitsAscii[k] = (char) (persianDigitsAscii[k] - 1584);
                output += persianDigitsAscii[k];
            }

             return output;
        }
    }
Revelationist answered 23/2, 2019 at 9:33 Comment(1)
If implemented correctly, this is fastest. But you should either use a string builder, or just covert your array back to a string in the end. Also, the input string may contain other characters, so you need to test for that.Skyway
B
1

Use this extension ,also for arabic keyboard for example : "۵", "٥" or "۴", "٤"

static char[][] persianChars = new char[][]
    {
        "0123456789".ToCharArray(),"۰۱۲۳۴۵۶۷۸۹".ToCharArray()
    };
    static char[][] arabicChars = new char[][]
    {
        "0123456789".ToCharArray(),"٠١٢٣٤٥٦٧٨٩".ToCharArray()
    }; 
    public static string toPrevalentDigits(this string src)
    {
        if (string.IsNullOrEmpty(src)) return null;
        for (int x = 0; x <= 9; x++)
        {
            src = src.Replace(persianChars[1][x], persianChars[0][x]);
        }
        for (int x = 0; x <= 9; x++)
        {
            src = src.Replace(arabicChars[1][x], arabicChars[0][x]);
        }
        return src;
    } 
Borders answered 26/2, 2019 at 5:39 Comment(0)
B
1

I recently use this code for 10 record with none-persian chars but reason was to slowly process so you must be check with LINQ before replace it

static Dictionary<char, char> LettersDictionary = new Dictionary<char, char>() {
            {'۰', '0'},
            {'۱', '1'},
            {'۲', '2'},
            {'۳', '3'},
            {'۴', '4'},
            {'۵', '5'},
            {'۶', '6'},
            {'۷', '7'},
            {'۸', '8'},
            {'۹', '9'}
        };

        public static string PersianToEnglish(this string persianStr)
        {
            if (persianStr.Any(x => LettersDictionary.Keys.Contains(x)))
            {
                foreach (var item in persianStr)
                {
                    try { persianStr = persianStr.Replace(item, LettersDictionary[item]); }
                    catch { }
                }
            }
            return persianStr;
        }
Bokbokhara answered 11/7, 2021 at 5:5 Comment(0)
K
0

You can use the Windows.Globalization.NumberFormatting.DecimalFormatter class to parse the string. This will parse strings in any of the supported numeral systems (as long as it is internally coherent).

Kelleher answered 24/9, 2013 at 18:57 Comment(0)
H
0

This will work well for converting Persian/Arabic numbers to English, too:

public static String convertToEnglish(String arabicNumber) {
    for (int i = 0; i <= 9; i++) {
        arabicNumber= arabicNumber.replace((char) (1776 + i),
                (char) (48 + i));
    }
    return arabicNumber;
}
Hemichordate answered 14/11, 2021 at 8:50 Comment(0)
H
0

For .Net6 or above

 public static string ConvertToNumeric(string text)
    {
        var result = new StringBuilder(text.Length);
        foreach (char ch in text)
        {
            result.Append(char.IsDigit(ch) ? char.GetNumericValue(ch) : ch.ToString());
        }
        return result.ToString();
    }
Hanselka answered 18/9, 2022 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.