web-dev-qa-db-ja.com

通貨文字列を10進数に変換しますか?

目的

このような通貨データを表示している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);
47
Mike Perrenoud

これは、提供したコードに最も近い方法です

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

負の数をサポートし、2番目の期間値が見つかった場合に停止し、有効なdecimal値ではない文字列の数を減らすオプションを次に示します。また、現在のコードにはない追加のケースを処理するために、OPには見られない他のいくつかの変更があります。

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

これはどうですか。ただし、1つの文字列値に対してのみ機能します。したがって、文字列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();
26
bonCodigo
decimal amount = decimal.Parse("$123,456.78",
NumberStyles.AllowCurrencySymbol |
NumberStyles.AllowThousands |
NumberStyles.AllowDecimalPoint);
9
bilal

より簡単なソリューションを次に示します。

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

そしてユニットテスト:

    [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());
    }
8
Red
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);
}
0
Richard