C# 解析末尾带有M或B的字符串双精度
是否有一种解析方法可以理解,例如:C# 解析末尾带有M或B的字符串双精度,c#,C#,是否有一种解析方法可以理解,例如: 1,250,000 = 1.25M 10,000,000 = 10M 10,500,000 = 10.5M 47,600,000,000 = 47.6B 换句话说,我需要将47.6B解析为一个double。我知道我可以手工完成,我想知道是否有直接的方法,比如说使用IFormatter?不,在.Net framework中没有这样的方法(也没有相反的方法可以格式化这样的值) 您需要找到执行此操作的库或自己编写方法 请注意,K/M可能意味着2^10/2^20或1
1,250,000 = 1.25M
10,000,000 = 10M
10,500,000 = 10.5M
47,600,000,000 = 47.6B
换句话说,我需要将47.6B解析为一个double。我知道我可以手工完成,我想知道是否有直接的方法,比如说使用
IFormatter
?不,在.Net framework中没有这样的方法(也没有相反的方法可以格式化这样的值)
您需要找到执行此操作的库或自己编写方法
请注意,K/M可能意味着2^10/2^20或10^3/10^6,并且可能是特定于语言的(正如您从
CultureInfo.NumberFormat
信息中看到的那样,.Net framework中也不存在此信息)此处的一些代码可以修改:
double
,或者根据需要将decimal
转换为double
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
名称空间测试仪
{
公共类FileSizeConverter
{
私有静态系统.Globalization.NumberFormatInfo numberFormat;
私有静态字典知识;
静态FileSizeConverter()
{
/*
//基本2/二进制“计算机”单元
knownUnits=新词典
{
{“”,1L},//没有一个单元与单元B(yte)相同
{“B”,1L},
{“KB”,1024L},
{“MB”,1024L*1024L},
{“GB”,1024L*1024L*1024L},
{“TB”,1024L*1024L*1024L*1024L}
//根据需要填充其余部分
};
*/
//十进制“收缩”单位
knownUnits=新词典
{
{“,1L},
{“M”,1000L*1000L},//百万
{“B”,1000L*1000L*1000L}//10亿(美国)
//根据需要填充其余部分
};
numberFormat=System.Globalization.CultureInfo.CurrentCulture.numberFormat;
}
公共十进制解析(字符串值)
{
//忽略实际值周围的空格
value=value.Trim();
字符串单位=提取单位(值);
string sizeAsString=value.Substring(0,value.Length-unit.Length).Trim();//修剪空格
长乘法器=乘法器或单位(单位);
十进制大小;
if(!decimal.TryParse(sizeAsString,System.Globalization.NumberStyles.Number,numberFormat,out size))
抛出新的ArgumentException(“非法数字”、“值”);
返回乘法器*大小;
}
私有布尔IsDigit(字符值)
{
//我们不想使用char.IsDigit,因为它可以接受深奥的unicode数字
如果(值<'0')返回false;
如果(值>'9')返回false;
返回true;
}
专用字符串提取单元(字符串大小为单位)
{
//从右开始,在第一位结束
int lastChar=sizewishunit.Length-1;
int unitLength=0;
虽然(unitLength)没有直接的方法可以做到这一点,但您可以使用switch…case
创建自定义方法来确定数字后缀(取决于特定的区域性和基数,例如基数2或基数10),并将其转换为double
(decimal
,如果您有舍入问题,则更推荐)。
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"));
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"));
}
}
}