Проблема здесь в том, что в одном случае .
означает десятичную точку, а в другом - разделитель тысяч. И тогда у вас есть ,
в качестве десятичного разделителя. Очевидно, что синтаксический анализатор не может «угадать», что имеется в виду, поэтому единственное, что вы можете сделать, - это принять решение о некоторых правилах обработки того или иного случая.
Если у вас есть контроль над пользовательским интерфейсом, лучшим подходом будет проверка пользовательского ввода и просто отклонение любого значения, которое не может быть проанализировано с объяснением того, какой формат ожидается.
Если у вас нет контроля над пользовательским интерфейсом, вторым лучшим вариантом будет проверить некоторые «правила», а затем придумать, какая культура подходит для данного заданного ввода, и попытаться выполнить его через decimal.TryParse
для этой заданной культуры.
Для данного ввода у вас могут быть следующие правила:
input.StartsWith("$")
-> en-US
input.StartsWith("£")
-> ru-RU
input.StartsWith("€")
|| input.EndsWith("€")
-> de-DE
Они могут разумно обрабатывать все случаи.
В коде:
static void Main(string[] args)
{
string[] inputs =
{
"$1.30",
"£1.50",
"€2,50",
"2,50 €",
"2.500,00 €"
};
for (int i = 0; i < inputs.Length; i++)
{
Console.Write((i + 1).ToString() + ". ");
if (decimal.TryParse(inputs[i], NumberStyles.Currency,
GetAppropriateCulture(inputs[i]), out var parsed))
{
Console.WriteLine(parsed);
}
else
{
Console.WriteLine("Can't parse");
}
}
}
private static CultureInfo GetAppropriateCulture(string input)
{
if (input.StartsWith("$"))
return CultureInfo.CreateSpecificCulture("en-US");
if (input.StartsWith("£"))
return CultureInfo.CreateSpecificCulture("en-GB");
if (input.StartsWith("€") || input.EndsWith("€"))
return CultureInfo.CreateSpecificCulture("de-DE");
return CultureInfo.InvariantCulture;
}
Выход:
- 1,30
- 1,50
- 2,50
- 2,50
- 2500,00