Анализ чисел с плавающей запятой: есть ли алгоритм Catch All?

Одна из забавных составляющих мультикультурного программирования - числовые форматы.

  • Американцы используют 10 000,50
  • Немцы используют 10.000,50
  • Французский использовать 10 000,50

Мой первый подход - взять строку, проанализировать ее в обратном направлении, пока я не найду разделитель, и использовать его в качестве десятичного разделителя. В этом есть очевидный недостаток: 10.000 будет интерпретировано как 10.

Другой подход: если строка содержит 2 разных нечисловых символа, используйте последний в качестве десятичного разделителя и отбросьте остальные. Если у меня только один, проверьте, повторяется ли он более одного раза, и отбрасывайте его, если есть. Если он появляется только один раз, проверьте, есть ли после него 3 цифры. Если да, отбросьте его, в противном случае используйте его как десятичный разделитель.

Очевидным «лучшим решением» было бы определение культуры пользователя или браузера, но это не сработает, если у вас есть француз, использующий Windows / браузер en-US.

Содержит ли .NET Framework какой-то мифический синтаксический анализатор с плавающей запятой, который лучше, чем Double.(Try)Parse() попытки автоматического определения формата чисел?

Ответов (4)

Решение

Я думаю, что лучшее, что вы можете сделать в этом случае, - это прислушаться к их мнению, а затем показать им, что, по вашему мнению, они имели в виду. Если они не согласны, покажите им формат, на который вы рассчитываете, и попросите их ввести его снова.

Я не знаю стороны проблемы ASP.NET, но у .NET есть довольно мощный класс: System.Globalization.CultureInfo . Вы можете использовать следующий код для анализа строки, содержащей значение типа double:

double d = double.Parse("100.20", CultureInfo.CurrentCulture);
//  -- OR --
double d = double.Parse("100.20", CultureInfo.CurrentUICulture);

Если ASP.NET каким-то образом (например, с использованием заголовков HTTP-запроса) передает CultureInfo текущего пользователя либо в CultureInfo.CurrentCulture, либо в CultureInfo.CurrentUICulture, они будут работать нормально.

Всем не угодишь. Если я ввожу десять как 10.000, а кто-то вводит десять тысяч как 10.000, вы не сможете справиться с этим, не зная культуры ввода. Каким-то образом определите культуру (браузер, системные настройки - каков вариант использования? ASP? Внутреннее приложение или открытое для всего мира?) Или предоставьте пример ожидаемого форматирования и используйте самый мягкий синтаксический анализатор, который вы можете. Наверное, что-то вроде:

double d = Double.Parse("5,000.00", NumberStyles.Any, CultureInfo.InvariantCulture);

Разница между 12,345 во французском и английском языках составляет 1000 раз. Если вы укажете ожидаемый диапазон, в котором max <1000 * min, вы можете легко догадаться.

Возьмем, к примеру, рост человека (включая младенцев и детей) в мм.

Используя диапазон 200–3000, ввод 1,800 или 1800 можно однозначно интерпретировать как 1 метр и 80 сантиметров, тогда как ввод 912,300 или 912,300 можно однозначно интерпретировать как 91 сантиметр и 2,3 миллиметра.