Разобрать не-ascii (unicode) числовую строку как целое число в .NET - PullRequest
11 голосов
/ 26 мая 2011

У меня есть строка, содержащая число в не ascii формате, например Unicode BENGALI DIGIT ONE (U + 09E7): "১"

Как мне разобрать это как целое число в .NET?

Примечание: я попытался использовать int.Parse(), указав формат бенгальской культуры с "bn-BD" в качестве IFormatProvider. Не работает.

Ответы [ 3 ]

5 голосов
/ 26 мая 2011

Вы можете создать новую строку, которая совпадает со старой строкой, за исключением того, что собственные цифры заменяются латинскими десятичными цифрами. Это можно сделать надежно, пройдя по символам и проверив значение char.IsDigit(char). Если эта функция возвращает true, тогда преобразуйте ее с char.GetNumericValue(char).ToString().

Как это:

static class DigitHelper
{
    public static string ConvertNativeDigits(this string text)
    {
        if (text == null)
            return null;
        if (text.Length == 0)
            return string.Empty;
        StringBuilder sb = new StringBuilder();
        foreach (char character in text)
        {
            if (char.IsDigit(character))
                sb.Append(char.GetNumericValue(character));
            else
                sb.Append(character);
        }
        return sb.ToString();
    }
}


int value = int.Parse(bengaliNumber.ConvertNativeDigits());
3 голосов
/ 26 мая 2011

Похоже, это невозможно с использованием встроенной функциональности:

Единственные цифры Unicode, которые .NET Framework анализирует как десятичные, - это цифры ASCII от 0 до 9,определяется значениями кода от U + 0030 до U + 0039.

...

Попытки разобрать значения кода Unicode для цифр полной ширины, арабских цифр и бенгальскийцифры терпят неудачу и выдают исключение.

(выделено мной)

Очень странно, поскольку CultureInfo("bn-BD").NumberFormat.NativeDigits содержит их.

0 голосов
/ 11 мая 2014

Найдя этот вопрос во время поиска аналогичного ответа, но не найдя ни одного из ответов, полностью соответствующих тому, что мне было нужно, я написал следующее, так как он хорошо обрабатывает признаки и быстрее дает сбой, если получить очень длинную строку. Это не значит, игнорировать любые символы группировки, такие как ,, ', , хотя их можно легко добавить, если кто-то захочет (а я нет):

public static int ParseIntInternational(this string str)
{
  int result = 0;
  bool neg = false;
  bool seekingSign = true; // Accept sign at beginning only.
  bool done = false; // Accept whitespace at beginning end or between sign and number.
                     // If we see whitespace once we've seen a number, we're "done" and
                     // further digits should fail.
  for(int i = 0; i != str.Length; ++i)
  {
    if(char.IsWhiteSpace(str, i))
    {
      if(!seekingSign)
        done = true;
    }
    else if(char.IsDigit(str, i))
    {
      if(done)
        throw new FormatException();
      seekingSign = false;
      result = checked(result * 10 + (int)char.GetNumericValue(str, i));
    }
    else if(seekingSign)
      switch(str[i])
      {
        case '﬩': case '+':
          //do nothing: Sign unchanged.
          break;
        case '-': case '−':
          neg = !neg;
          break;
        default:
          throw new FormatException();
      }
    else throw new FormatException();
  }
  if(seekingSign)
    throw new FormatException();
  return neg ? -result : result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...