C# int 和非英语数字 [已关闭]

问题描述 投票:0回答:2

C#

int
数据类型可以保存文化特定数字,如东方阿拉伯语 数字吗?例如。
"123"
将会

١٢٣

我正在使用 SoapUI 发送请求并接收响应。 Web 服务是用 c# 编写的。

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

“无法解析该值”。

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

有人可以帮忙吗?

感谢您的回答!

c# integer arabic culture
2个回答
2
投票

您可以尝试使用 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

1
投票

int
类型(以及任何其他数字类型)仅存储并且不关心/知道原始字符串是什么格式。字符串表示仅影响输入和输出,而不影响值计算或存储

C# 通过

Globalization.CultureInfo
支持语言环境国际化,您只需指定正确的区域性(在本例中为波斯语),以便打印和解析正常工作。在
CultureInfo
中,有
NumberFormatInfo.NativeDigits
存储该语言环境的本地数字。如果您正确设置
NumberFormatInfo.DigitSubstitution
,将使用正确的数字系统打印输出。不幸的是,虽然这适用于格式化输出,但
Int.Parse
不使用该信息来解析本机数字中的数字,因此它无法用于格式化输入

但是,解析方法唯一识别的数字是基本拉丁数字 0-9,代码点从 U+0030 到 U+0039。如果向数字解析方法传递包含任何其他数字的字符串,该方法将抛出 FormatException

在.NET中解析数字字符串

这意味着您必须自己翻译这些数字。这是适用于任何文化

的解决方案
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 for Persian locales
            // although looks almost the same, you need to use 
            // Arabic locales like "ar" or "ar-SA" to parse
            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)和 not 波斯数字(01234567789 - 代码点 U+06F0-U+06F9)

© www.soinside.com 2019 - 2024. All rights reserved.