2017-04-21 52 views
1

的M或B是否有明白,例如解析方法:解析字符串雙用在端

1,250,000 = 1.25M 
10,000,000 = 10M 
10,500,000 = 10.5M 
47,600,000,000 = 47.6B 

換句話說,我需要47.6B解析成一個雙。我知道我可以用手做這個,我想知道是否有直接的方法,比如使用IFormatter

+1

有沒有直接的方法來做到這一點,但你可以使用'開關... case'確定數字後綴(取決於特定文化和基數,如基地2或基地10創建自定義的方法)並將其轉換爲double(如果有舍入問題,則更推薦使用「decimal」)。 –

回答

2

不,在.Net框架中沒有這樣的方法(並且沒有相反的格式化這樣的值)。

您需要找到自己編寫或編寫方法的庫。

請注意,K/M可能表示2^10/2^20或10^3/10^6,並且可能是語言特定的(同樣,該信息不存在於.Net框架中,正如您可以從CultureInfo.NumberFormat信息中看到的那樣)

0

從這裏的一些代碼可以適應:

只要指定你自己承認十進制名單「收縮」單位:

static FileSizeConverter() 
    { 
     // decimal "contraction" units 

     knownUnits = new Dictionary<string, long> 
     { 
      { "", 1L }, 
      { "M", 1000L * 1000L }, // million 
      { "B", 1000L * 1000L * 1000L } // billion (usa) 
      // fill rest as needed 
     }; 

     numberFormat = System.Globalization.CultureInfo.CurrentCulture.NumberFormat; 
    } 

就用這樣的:

var converter = new FileSizeConverter(); 
    Console.WriteLine(converter.Parse("1.25M")); 
    Console.WriteLine(converter.Parse("10M")); 
    Console.WriteLine(converter.Parse("10.5M")); 
    Console.WriteLine(converter.Parse("47.6B")); 

使用double在解析器,或轉換從decimaldouble如果這是你需要的。


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 

namespace Rextester 
{ 

    public class FileSizeConverter 
    { 
     private static System.Globalization.NumberFormatInfo numberFormat; 
     private static Dictionary<string, long> knownUnits; 

     static FileSizeConverter() 
     { 
      /* 

      // base2/binary "computer" units 

      knownUnits = new Dictionary<string, long> 
      { 
       { "", 1L },         // no unit is same as unit B(yte) 
       { "B", 1L }, 
       { "KB", 1024L }, 
       { "MB", 1024L * 1024L}, 
       { "GB", 1024L * 1024L * 1024L}, 
       { "TB", 1024L * 1024L * 1024L * 1024L} 
       // fill rest as needed 
      }; 

      */ 

      // decimal "contraction" units 

      knownUnits = new Dictionary<string, long> 
      { 
       { "", 1L }, 
       { "M", 1000L * 1000L }, // million 
       { "B", 1000L * 1000L * 1000L } // billion (usa) 
       // fill rest as needed 
      }; 

      numberFormat = System.Globalization.CultureInfo.CurrentCulture.NumberFormat; 
     } 

     public decimal Parse(string value) 
     { 
      // ignore spaces around the actual value 
      value = value.Trim(); 

      string unit = ExtractUnit(value); 
      string sizeAsString = value.Substring(0, value.Length - unit.Length).Trim(); // trim spaces 

      long multiplicator = MultiplicatorForUnit(unit); 
      decimal size; 

      if (!decimal.TryParse(sizeAsString, System.Globalization.NumberStyles.Number, numberFormat, out size)) 
       throw new ArgumentException("illegal number", "value"); 

      return multiplicator * size; 
     } 

     private bool IsDigit(char value) 
     { 
      // we don't want to use char.IsDigit since it would accept esoterical unicode digits 
      if (value < '0') return false; 
      if (value > '9') return false; 

      return true; 
     } 

     private string ExtractUnit(string sizeWithUnit) 
     { 
      // start right, end at the first digit 
      int lastChar = sizeWithUnit.Length - 1; 
      int unitLength = 0; 

      while (unitLength <= lastChar 
       && sizeWithUnit[lastChar - unitLength] != ' '  // stop when a space 
       && !IsDigit(sizeWithUnit[lastChar - unitLength])) // or digit is found 
      { 
       unitLength++; 
      } 

      return sizeWithUnit.Substring(sizeWithUnit.Length - unitLength).ToUpperInvariant(); 
     } 

     private long MultiplicatorForUnit(string unit) 
     { 
      unit = unit.ToUpperInvariant(); 

      if (!knownUnits.ContainsKey(unit)) 
       throw new ArgumentException("illegal or unknown unit", "unit"); 

      return knownUnits[unit]; 
     } 
    } 

    public class Program 
    { 
     public static void Main(string[] paramList) 
     { 
      var converter = new FileSizeConverter(); 
      Console.WriteLine(converter.Parse("1.25M")); 
      Console.WriteLine(converter.Parse("10M")); 
      Console.WriteLine(converter.Parse("10.5M")); 
      Console.WriteLine(converter.Parse("47.6B")); 
     } 
    } 
}