使用货币符号解析值

时间:2016-03-15 02:16:37

标签: c# .net parsing

我在解析货币时已经考虑了多个SO问题,最好的(推荐的)方式似乎是我在下面尝试的方式:

var payout = decimal.Parse("$2.10", NumberStyles.Currency | NumberStyles.AllowDecimalPoint);

但是,它会抛出异常:输入字符串的格式不正确。

我不知道自己做错了什么?

修改

感谢您的回答。附加信息:我给出的硬编码货币值只是一个例子。我有一份货币清单:

  

€2,66

     

$ 2.10

     

$ 5.55

     

我无法提前确定文化信息。有什么想法吗?

5 个答案:

答案 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);
    }