从字符串中删除字符

时间:2016-04-06 09:31:43

标签: c# string csv io

我遇到一些非常简单的问题 - 我觉得我错过了一些非常明显的事情。

我有一个以分号分隔的.csv文件。在这个文件中有几个包含像“1.300”这样的点的数字,但是也包含了像“2015.12.01”这样的日期。任务是查找和删除所有点,但只有那些数字和日期的点。日期和数字是完全可变的,永远不会在文件中的相同位置。

我现在的问题:处理这个问题的'最佳'方法是什么?

从程序员的角度来看:这是一个很好的解决方案,只需在每个半导体上进行分割,计算点数,如果只有一个点,则将其删除?这是解决我现在想到的问题的唯一方法。

示例源文件:

2015.12.01;
13.100;
500;
1.200;
100;

示例结果:

2015.12.01;
13100;
500;
1200;
100;

3 个答案:

答案 0 :(得分:5)

如果您可以依赖日期有两个点和数字只有一个这一事实,您可以将其用作过滤器:

string s = "123.45";
if (s.Count(x => x == '.') == 1)
{
    s = s.Replace(".", null);
}

答案 1 :(得分:1)

我不会依赖点的数量,因为可以犯错误。

您可以使用double.TryParse安全地测试字符串是否为数字

var data = "2015.12.01;13.100;500;1.200;100;";

var dataArray = data.Split(';');

foreach (var s in dataArray)
{
    double result;
    if(double.TryParse(s,out result))
        // implement your logic here
        Console.WriteLine(s.Replace(".",string.Empty));
}

答案 2 :(得分:1)

源文件看起来像是由机器上运行的程序生成的有效文件,该机器的语言环境使用.作为千分隔符(欧洲大部分地区)和日期分隔符(我认为只有德语语言环境)。此类语言环境还使用;作为列表分隔符。

如果问题只是如何解析这些日期,数字,那么答案就是将正确的文化传递给解析函数,例如:decimal.Parse("13.500",new CultureInfo("de-at"))将返回13500.但实际问题是数据必须被送到另一个使用.作为小数分隔符的程序。

最安全的选项是更改导出程序使用的语言环境,例如,如果导出程序是.NET程序,SSIS包中的语言环境等,则将文档CultureInfo更改为en-gb之类的语言环境。使用.导出并避免使用奇怪的日期格式。这假设管道中的下一个程序不使用德语作为日期,英语作为数字

另一种选择是加载文本,使用适当的语言环境解析字段,然后以下一个程序所需的格式导出它们。

最后,正则表达式可用于仅匹配数字字段并删除点。这可能有点棘手,取决于实际内容。

例如,如果只有一千个分隔符,(\d+)\.(\d{3})可用于匹配数字。如果某些文本字段包含类似的值,则可能会失败。或者;(\d+)\.(\d{3});只能匹配一个完整的字段,除了第一个和最后一个字段,例如:

Regex.Replace("1.457;2016.12.30;13.000;1,50;2015.12.04;13.456",@";(\d+)\.(\d{3});",@"$1$2;")

产生:

1.457;2016.12.3013000;1,50;2015.12.04;13.456

;或第一个/最后一个字段之间的数字匹配的正则表达式可以是

 (^|;)(\d+)\.(\d{3})(;|$)

这会产生1457;2016.12.30;13000;1,50;2015.12.04;13456,例如:

var data="1.457;2016.12.30;13.000;1,50;2015.12.04;13.456";

var pattern=@"(^|;)(\d+)\.(\d{3})(;|$)";
var replacement=@"$1$2$3$4";

var result= Regex.Replace(data,pattern,replacement);

正则表达式优于分割和替换字符串的优势在于它的很多更快,内存效率更高。 Regex只计算源中的索引,而不是为每个拆分操作生成临时字符串。请求最终文本结果时,仅生成 字符串对象。这导致了更少的分配和垃圾收集。

即使在中等大小的文件中,这也可以使性能提高10倍