6

我需要在我的应用程序中接受 3 种十进制数据格式:

  • 123456,78 => 123456.78
  • 123,456.78 => 123456.78
  • 123456.78 => 123456.78

我不能假设在特定情况下会使用一种格式。我需要的是从字符串中获取十进制值,无论它以哪种格式给出。

有没有聪明的方法来做到这一点?

我试图使用

var culture = CultureInfo.CreateSpecificCulture("en-US");

但这似乎不适用于 wp7。

到目前为止,我已经这样做了:

public static class Extensions
{

    public static decimal toDecimal(this string s)
    {
        decimal res;

        int comasCount=0;
        int periodsCount=0;

        foreach (var c in s)
        {
            if (c == ',')
                comasCount++;
            else if (c == '.')
                periodsCount++;
        }

        if (periodsCount > 1)
            throw new FormatException();
        else if(periodsCount==0 && comasCount > 1)
            throw new FormatException();

        if(comasCount==1)
        {
            // pl-PL
            //parse here
        }else
        {
            //en-US
            //parse here
        }

        return res;
    }
}
4

3 回答 3

4

尝试使用var culture = new CultureInfo("en-US");来创造文化。将该文化传递给decimal.Parsedecimal.TryParse将为每种文化适当地解析文本。

现在,请记住,每种文化都可以毫无问题地解析文本,但不会按照原始文化所代表的方式解析它。例如decimal.TryParse("1000,314", NumberStyles.Number, new CultureInfo("en-US"), out result)将导致成功和 1000314m,而不是 1000.314m。而decimal.TryParse("1000,314", NumberStyles.Number, new CultureInfo("fr-FR"), out result)将导致1000.314m。

于 2012-08-21T00:12:37.150 回答
2

你可以尝试这样的事情:

public static decimal ParseDecimalNumber( string s , string groupSeparators , string decimalPoints )
{
  NumberFormatInfo nfi   = (NumberFormatInfo) CultureInfo.InvariantCulture.NumberFormat.Clone() ;
  NumberStyles     style = NumberStyles.AllowLeadingWhite
                         | NumberStyles.AllowLeadingSign
                         | NumberStyles.AllowThousands
                         | NumberStyles.AllowDecimalPoint
                         | NumberStyles.AllowTrailingSign
                         | NumberStyles.AllowTrailingWhite
                         ;
  decimal          value ;
  bool             parsed = false ;

  for ( int i = 0 ; !parsed && i < groupSeparators.Length ; ++i )
  {

    nfi.NumberGroupSeparator = groupSeparators.Substring(i,1) ;

    for ( int j = 0 ; !parsed && j < decimalPoints.Length ; ++j )
    {
      if ( groupSeparators[i] == decimalPoints[j] ) continue ; // skip when group and decimal separator are identical

      nfi.NumberDecimalSeparator = decimalPoints.Substring(j,1) ;

      parsed = Decimal.TryParse( s , style , nfi , out value ) ;

    }
  }

  if ( !parsed ) throw new ArgumentOutOfRangeException("s") ;

  return value ;

}

用法很简单:

string groupSeparators = "., " ;
string decimalPoints   = ".,"  ;
Decimal value = ParseDecimalNumber( someStringContainingANumericLiteral , groupSeparators , decimalPoints ) ;
于 2012-08-21T00:34:36.663 回答
0

三个不同的TryParse调用NumberStylesIFormatProvider设置为 null 应该可以做到这一点。

于 2012-08-20T23:48:47.463 回答