我在解析货币时已经考虑了多个SO问题,最好的(推荐的)方式似乎是我在下面尝试的方式:
var payout = decimal.Parse("$2.10", NumberStyles.Currency | NumberStyles.AllowDecimalPoint);
但是,它会抛出异常:输入字符串的格式不正确。
我不知道自己做错了什么?
修改
感谢您的回答。附加信息:我给出的硬编码货币值只是一个例子。我有一份货币清单:
€2,66
$ 2.10
$ 5.55
等
我无法提前确定文化信息。有什么想法吗?
答案 0 :(得分:3)
类似的方法 @ un-lucky 被提及作为答案之一,我尝试将其设为通用并适用于每个Symbol/Format
public static decimal ParseCurrencyWithSymbol(string input)
{
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures)
.GroupBy(c=> c.NumberFormat.CurrencySymbol)
.ToDictionary(c=> c.Key, c=>c.First());
var culture = cultures.FirstOrDefault(c=>input.Contains(c.Key));
decimal result = 0;
if(!culture.Equals(default(KeyValuePair<string,CultureInfo>)))
{
result = decimal.Parse(input, NumberStyles.Currency | NumberStyles.AllowDecimalPoint, culture.Value);
}
else
{
if( !decimal.TryParse(input, out result))
{
throw new Exception("Invalid number format");
}
}
return result;
}
<强>用法强>
decimal output = ParseCurrencyWithSymbol("$2.10");
工作Code
答案 1 :(得分:1)
您可以尝试这样:
decimal currencyValue;
string inputCurrency = "$12.6";
if (decimal.TryParse(inputCurrency, NumberStyles.Currency, CultureInfo.CreateSpecificCulture("en-US"), out currencyValue))
{
// proceed with currencyValue
}
else
{
//Show error ; Conversion failed
}
要处理所有货币,您可以使用以下内容:
Dictionary<char, string> currencyCulture = new Dictionary<char, string>();
currencyCulture.Add('$', "en-US");
currencyCulture.Add('€', "en-IE");
// populate all posible values here
decimal currencyValue;
string inputCurrency = "€2,66";
char currencySymbol= inputCurrency.ToCharArray()[0];
CultureInfo currentCulture= CultureInfo.CreateSpecificCulture(currencyCulture[currencySymbol]);
if (decimal.TryParse(inputCurrency, NumberStyles.Currency, currentCulture, out currencyValue))
{
// proceed with currencyValue
}
else
{
//Show error ; Conversion failed
}
您可以从here
中选择文化名称答案 2 :(得分:0)
根据您的具体情况,您可以使用以下代码段:
var payout = decimal.Parse("$2.10".Replace("$",""));
如果您不知道货币符号是什么,请尝试以下解决方案:
string _money = "$2.10";
var payout = decimal.Parse(_money.Substring(1));
处理逗号和小数点要困难得多:如果这是问题,请参阅成员@un-lucky提供的解决方案。
希望这可能会有所帮助。
答案 3 :(得分:0)
CleanCurrency
方法怎么样?
/// Loops each char in the string and returns only numbers, . or ,
static double? CleanCurrency(string currencyStringIn) {
string temp = "";
int n;
for (int i = 0; i < currencyStringIn.Length; i++) {
string c = currencyStringIn.Substring(i, 1);
if (int.TryParse(c, out n) || c == "." || c == ",") {
temp += c;
}
}
if (temp == "") {
return null;
else {
return double.Parse("0" + temp);
}
}
这里的想法是获取实际数字而不管字符串内容是什么。
double? payout = CleanCurrency("$3.50");
答案 4 :(得分:0)
我已经阐述了哈里·普拉萨德(Hari Prasad)的答案。这样,您可以最小化培养结果。使用您可能在应用程序中使用的支持更新“ SupportedCultures”。
private static readonly List<string> SupportedCultures = new List<string> {"en-US", "en-GB", "fr-FR"};
public static void Main()
{
var (amount, culture) = ParseCurrencyWithSymbol("$256.12");
Console.WriteLine($"{culture?.Name} | {amount}");
var (amount2, culture2) = ParseCurrencyWithSymbol("£389.17");
Console.WriteLine($"{culture2?.Name} | {amount2}");
var (amount3, culture3) = ParseCurrencyWithSymbol("€421,10");
Console.WriteLine(culture3 != null ? $"{culture3.Name} | {amount3}" : "Failed!");
}
public static Tuple<decimal?, CultureInfo> ParseCurrencyWithSymbol(string input)
{
var culture = CultureInfo.GetCultures(CultureTypes.AllCultures)
.Where(x => SupportedCultures.Contains(x.Name))
.FirstOrDefault(c => input.Contains(c.NumberFormat.CurrencySymbol));
if (culture == null) return new Tuple<decimal?, CultureInfo>(null, null);
return new Tuple<decimal?, CultureInfo>(decimal.Parse(input,
NumberStyles.Currency | NumberStyles.AllowCurrencySymbol |
NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, culture), culture);
}