【发布时间】:2011-06-22 04:37:49
【问题描述】:
我正在开发一个导入数千行的应用程序,其中每一行的格式如下:
|* 9070183020 |04.02.2011 |107222 |M/S SUNNY MEDICOS |GHAZIABAD | 32,768.00 |
我正在使用以下Regex 将行拆分为我需要的数据:
Regex lineSplitter = new Regex(@"(?:^\|\*|\|)\s*(.*?)\s+(?=\|)");
string[] columns = lineSplitter.Split(data);
foreach (string c in columns)
Console.Write("[" + c + "] ");
这给了我以下结果:
[] [9070183020] [] [04.02.2011] [] [107222] [] [M/S SUNNY MEDICOS] [] [GHAZIABAD] [] [32,768.00] [|]
现在我有两个问题。
1.如何删除空结果。我知道我可以使用:
string[] columns = lineSplitter.Split(data).Where(s => !string.IsNullOrEmpty(s)).ToArray();
但是是否有任何内置方法可以删除空结果?
2.如何移除最后一个管道?
谢谢你的帮助。
问候,
尤格什。
编辑:
我想我的问题有点被误解了。这从来都不是关于我怎么能做到的。这只是关于 如何通过更改上述代码中的 Regex 来做到这一点。
我知道我可以通过多种方式做到这一点。我已经使用上面提到的带有Where 子句的代码和另一种更快(超过两倍)的方式完成了它:
Regex regex = new Regex(@"(^\|\*\s*)|(\s*\|\s*)");
data = regex.Replace(data, "|");
string[] columns = data.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
其次,作为一个测试用例,我的系统在原始方法中可以在不到 1.5 秒的时间内解析 92k+ 行,在第二种方法中不到 700 毫秒,我永远不会找到超过几千案例,所以我认为我不需要考虑这里的速度。在我看来,在这种情况下考虑速度是过早的优化。
我找到了第一个问题的答案:Split 无法完成,因为没有内置这样的选项。
仍在寻找我第二个问题的答案。
【问题讨论】:
-
回答你的第一个问题,我相信正则表达式的分组部分应该是
@"(.+?)"。否则有可能匹配空白(这就是你现在所拥有的)。 -
在这种情况下几乎不重要 Jeff。它会给出完全相同的结果。
-
就像您提到数千个条目的注释一样:使用 String.Split 然后进行更多的字符串处理比首先使用正则表达式要快得多。
-
您可以通过修改 RegEx 来删除最后一个管道。检查我对进行此类拆分的 RegEx 的回答(尽管您仍然会得到空记录,但是在使用不修剪的拆分时无济于事)。