Подтвердить что ты не робот

Преобразовать строку валюты в десятичную?

Цель

Сортировка string, который численно отображает данные о валюте, такие как $1,995.94, в наборе данных.

код

В настоящее время я использую приведенный ниже пример кода, чтобы преобразовать значение string в decimal, чтобы я мог правильно сортировать его.

if (sortBy == "checkAmount")
{
    StringBuilder sb = new StringBuilder();
    foreach (var c in Convert.ToString(p.GetType().GetProperty(sortBy).GetValue(p, null)))
    {
        if (!char.IsDigit(c) && c != '.') { continue; }
        sb.Append(c);
    }
    return Convert.ToDecimal(sb.ToString());
}
else
{
    return p.GetType().GetProperty(sortBy).GetValue(p, null);
}

Проблема

Какой лучший способ сделать это? Он работает, и это круто, но это не очень элегантно.

Окончательное решение

Ответ, предоставленный Servy работает как ожидалось, и я использовал эту реализацию некоторое время, но коллега и я нашли еще лучший способ, поэтому я документирую его здесь. Кстати, в итоге я решил использовать это решение.

decimal.Parse(input, NumberStyles.AllowCurrencySymbol | NumberStyles.Number);
4b9b3361

Ответ 1

Вот метод, который наиболее точно напоминает код, который вы предоставили

public static decimal Parse(string input)
{
    return decimal.Parse(Regex.Replace(input, @"[^\d.]", ""));
}

Вот опция, которая будет поддерживать отрицательные числа, и остановится, если найдет значение второго периода, таким образом уменьшив количество возвращаемых строк, которые недействительны decimal. Он также имеет несколько других модификаций, которые не наблюдаются в OP, чтобы обрабатывать дополнительные случаи, которые ваш текущий код не делает.

public static decimal Parse(string input)
{
    return decimal.Parse(Regex.Match(input, @"-?\d{1,3}(,\d{3})*(\.\d+)?").Value);
}

Ответ 2

Как насчет этого, но работает только для одного строкового значения. Поэтому вам нужно получить строку split на $, а затем выполнить преобразование при сохранении в array или list

 using System.Globalization;
    //rest of your code

          string str = "$50,550.20";
          decimal decval;
          bool convt = decimal.TryParse(str, NumberStyles.Currency,
            CultureInfo.CurrentCulture.NumberFormat, out decval);
          if (convt) 
          Console.WriteLine(decval);
          Console.ReadLine();

Ответ 3

decimal amount = decimal.Parse("$123,456.78",
NumberStyles.AllowCurrencySymbol |
NumberStyles.AllowThousands |
NumberStyles.AllowDecimalPoint);

Ответ 4

Вот более простое решение:

    public static decimal ToDecimal(this string str)
    {
        return decimal.Parse(str, NumberStyles.Currency);
    }

и unit test:

    [Test]
    public void ToDecimal_Convert_String_To_Decimal()
    {
        Assert.AreEqual(1234M, "1234".ToDecimal());
        Assert.AreEqual(-1234.56M, "$(1,234.56)".ToDecimal());
        Assert.AreEqual(1234.56M, "$1,234.56".ToDecimal());
    }

Ответ 5

public static decimal ToDecimalFromStringDecimalOrMoneyFormattedDecimal(this string s)
{
    try
    {
        return decimal.Parse(s);
    }
    catch
    {
        var numberWithoutMoneyFormatting = Regex.Replace(s, @"[^\d.-]", "");
        return decimal.Parse(numberWithoutMoneyFormatting);
    }
}

[Test]
public void Test_ToDecimalFromStringDecimalOrMoneyFormattedDecimal()
{
    Assert.That("$ 500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)500);
    Assert.That("R -500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-500);
    Assert.That("-$ 500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-500);
    Assert.That("P 500.90".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)500.9);
    Assert.That("$ -50 0,090,08.08".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-50009008.08);
}