C#int和非英语数字

问题描述

C#int数据类型是否可以像 Eastern Arabic 数字一样保存文化特定数字?例如。 "123"

١٢٣

我正在与SoapUI一起发送请求和接收响应。 该Web服务是用 c#编写的。

但是,当我在Soap UI中输入这些东阿拉伯语数字时,它说

“无法解析该值”。

尚不清楚是Soap UI问题还是 c#问题。

有人可以帮忙吗?

感谢您的回答!

解决方法

您可以尝试使用char.GetNumericValue将特定于文化的数字(例如波斯语)转换为通用的0..9

private static bool TryParseAnyCulture(string value,out int result) {
  result = default(int);

  if (null == value)
    return false;

  StringBuilder sb = new StringBuilder(value.Length);

  foreach (char c in value) {
    double d = char.GetNumericValue(c);

    // d < 0      : character is not a digit,like '-'
    // d % 1 != 0 : character represents some fraction,like 1/2
    if (d < 0 || d % 1 != 0)
      sb.Append(c);
    else
      sb.Append((int)d);
  }

  return int.TryParse(sb.ToString(),out result);
}

演示:

string value = "١٢٣"; // Eastern Arabic Numerals (0..9 are Western)

Console.Write(TryParseAnyCulture(value,out var result) ? $"{result}" : "???");

结果:

123
,

int类型(和任何其他数字类型)仅存储,并且不关心/不知道原始字符串所采用的格式。字符串表示法仅会影响输入和输出

C#支持通过System.Globalization.CultureInfo进行国际化的语言环境,您只需要指定正确的区域性(在这种情况下为波斯语)即可正确进行打印和解析。在CultureInfo中,有NumberFormatInfo.NativeDigits存储该语言环境的本地数字。如果您set NumberFormatInfo.DigitSubstitution correctly,将使用正确的数字系统打印输出。不幸的是,尽管这对格式化输出有效,但是Int.Parse并不使用该信息来解析本机数字,因此您必须自己转换数字。这是适用于任何文化的解决方案

using System;
using System.Globalization;

public class Program
{
    public static string GetWesternRepresentation(string input,CultureInfo cultureInfo)
    {
        var nativeDigits = cultureInfo.NumberFormat.NativeDigits;
        return input.Replace(cultureInfo.NumberFormat.NumberDecimalSeparator,".")
                    .Replace(cultureInfo.NumberFormat.NumberGroupSeparator,",")
                    .Replace(cultureInfo.NumberFormat.NegativeSign,"-")
                    .Replace(cultureInfo.NumberFormat.PositiveSign,"+")
                    .Replace(nativeDigits[0],"0")
                    .Replace(nativeDigits[1],"1")
                    .Replace(nativeDigits[2],"2")
                    .Replace(nativeDigits[3],"3")
                    .Replace(nativeDigits[4],"4")
                    .Replace(nativeDigits[5],"5")
                    .Replace(nativeDigits[6],"6")
                    .Replace(nativeDigits[7],"7")
                    .Replace(nativeDigits[8],"8")
                    .Replace(nativeDigits[9],"9");
    }

    public static void Main()
    {
        try
        {
            var culture = new CultureInfo("fa"); // or fa-Ir for Iranian Persian
            string input = "۱۲۳";
            // string input = "١٢٣";    // won't work although looks almost the same
            string output = GetWesternRepresentation(input,culture);
            Console.WriteLine("{0} -> {1}",input,output);
            int number = Int32.Parse(output,CultureInfo.InvariantCulture);
            Console.WriteLine("Value: {0}",number);
        }
        catch (FormatException)
        {
            Console.WriteLine("Bad Format");
        }
        catch (OverflowException)
        {
            Console.WriteLine("Overflow");
        }
    }
}

您可以在.NET Fiddle

上尝试

现在,您可能会看到,将输入更改为带注释的行时,尽管字符串看起来几乎相同,但它不起作用。那是因为您上面的数字是东部阿拉伯数字(٠١٢٣٤٥٦٧٨٩-代码点U + 0660-U + 0669)和不是波斯数字(۰۱۲۳۴۵۶۷۸۹-代码点U + 06F0-U + 06F9)