【问题标题】:Converting Scientific notation values into numeric one while reading csv file which is serialized automatically在读取自动序列化的 csv 文件时将科学记数法值转换为数字
【发布时间】:2019-03-26 05:40:06
【问题描述】:

我有一个 csv 文件,我必须将其导入数据库。当通过流阅读器读取文件时,一些值被转换为科学计数法,如“5.00E+11”。我必须将其恢复为原始值。这是由一项工作完成的,因此我无法手动将单元格格式化为“文本”或“特殊”。当该单元格被格式化为“文本”或“特殊”时,它可以正常工作。

我需要如下结果:

    "5.00E+11" should be converted into "500000000000"
    "8.12E+12" should be converted into "8122280000000"

我读取文件的代码如下:

    /// <summary>
    /// This is used to read the csv file
    /// </summary>
    using (StreamReader reader = new StreamReader(comepleteFilePath))
    {
       values = reader.ReadToEnd()
                      .Split(new string[] 
                      { Environment.NewLine },
                       StringSplitOptions.RemoveEmptyEntries
                      ).ToList();
     }         

    var _tempNuber = Convert.ToString(splits[13].Trim()); 

如下图

【问题讨论】:

标签: c# csv console-application inputstreamreader


【解决方案1】:

首先,您应该使用像 CsvHelper 这样的专用 CSV 解析器,这可能会为您节省大量时间。

其次,如果要解析数字,请使用 decimaldouble Parse 之类的选项之一。在这种情况下NumberStyles.Float

decimal.Parse(number, NumberStyles.Float);

NumberStyles.Float

表示AllowLeadingWhiteAllowTrailingWhiteAllowLeadingSignAllowDecimalPointAllowExponent 样式是 用过的。这是一种合数样式。

允许指数

表示数字字符串可以是指数表示法。这 AllowExponent 标志允许解析的字符串包含指数 以“E”或“e”字符开头,后跟一个 可选的正号或负号和一个整数。换句话说,它 成功解析 nnnExx、nnnE+xx 和 nnnE-xx 形式的字符串。 它不允许使用小数分隔符或在有效位上签名或 尾数;要允许解析字符串中的这些元素,请使用 AllowDecimalPoint 和 AllowLeadingSign 标志,或使用复合样式 包括这些单独的标志。

更新

您可以使用正则表达式来尝试确定该字段是否包含实际数字。像 \d.\d+E[+-]\d+或最好的选择 decminal.TryParse具有适当的选项。

【讨论】:

  • 该字段不仅是数字;有些数据是文本,有些是数字,有些是文本和数字的组合,所以我不能直接对任何格式化程序进行硬编码。问题仅限于大数值。
  • 我必须检查它是否是一个数值和科学计数法,然后必须使用:decimal.Parse(number, NumberStyles.Float);
  • @SatishChandraMaurya decminal.TryParse 会同时做这两件事
【解决方案2】:

您可以将该字符串解析为十进制

    string s = "5.00E+11";
    decimal d = decimal.Parse(s, NumberStyles.Float);

输出

500000000000

如果你只想应用解析一个指数元素,那么你可以检查给定的字符串是否是指数的

double d = 0;
if(str.Contains("E") && double.TryParse(str, out d))
{
   //Your conversion
}

POC:.net fiddle

【讨论】:

  • 我无法检查“E”,因为文本值也可能包含该字符。所以我必须检查“+”字符而不是那个 ie。 str.Contains("+")
  • 我对@9​​87654325@ 进行了额外的条件检查,这对于检查传递的字符串是否为双精度类型且Exp 编号始终包含+ and E/e 很重要
【解决方案3】:

检查该字段是否为数字和科学记数法,然后格式化为:

var _tempNuber =  splits[13].Trim().Contains('+') ? decimal.Parse(splits[13].Trim(), NumberStyles.Float).ToString() 
                                                  : splits[13].Trim();

【讨论】:

  • 如果splits[13] 包含类似1+2 的内容会怎样
  • 没有机会,因为那里不允许有特殊字符
  • 您的最后一条评论是矛盾的,因为您提到了有问题的指数数(它在字符串中包含+)并且在最后一条语句中您说没有特殊字符...我不知道存在什么值splits[13],但是您在答案中建议的解决方案是不可持续的(我相信)如果它对您有用,那么我对您的回答感到高兴
  • @Prasad 让我说清楚;在将数据导出到 csv 文件的数据库表中,不允许特殊字符从应用程序的前端进入该列。现在在 csv 文件的 Cell[13] 中,值为“500000000000”,但是当我通过上面的代码读取该字段时,由于自动序列化 excel,它被读取为“5.00E+11”。
猜你喜欢
  • 2019-02-25
  • 1970-01-01
  • 2019-04-21
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 2023-02-17
  • 2021-12-23
  • 2018-12-12
相关资源
最近更新 更多