C#Regex.Split:删除空结果

我正在开发一个导入数千行的应用程序,其中每行都有如下格式:

|* 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

仍在寻找我的第二个问题的答案。

 Regex lineSplitter = new Regex(@"[\s*\*]*\|[\s*\*]*"); var columns = lineSplitter.Split(data).Where(s => s != String.Empty); 

或者你可以简单地做:

 string[] columns = data.Split(new char[] {'|'}, StringSplitOptions.RemoveEmptyEntries); foreach (string c in columns) this.textBox1.Text += "[" + c.Trim(' ', '*') + "] " + "\r\n"; 

不,没有选项可以删除RegEx.Split的空条目,就像String.Split一样。

您也可以使用比赛。

我认为这可能相当于删除空字符串:

 string[] splitter = Regex.Split(textvalue,@"\s").Where(s => s != String.Empty).ToArray(); 

作为分割的替代方法,当分隔符也出现在输入的开头和结尾时,这总是会引起麻烦,您可以尝试匹配管道中的内容:

 foreach (var token in Regex.Matches(input, @"\|\*?\s*(\S[^|]*?)\s*(?=\|)")) { Console.WriteLine("[{0}]", token.Groups[1].Value); } // Prints the following: // [9070183020] // [04.02.2011] // [107222] // [M/S SUNNY MEDICOS] // [GHAZIABAD] // [32,768.00] 

在你的情况下根本不要使用正则表达式。 它似乎不需要,并且正则表达式比直接使用字符串函数慢得多(并且具有更高的开销)。

所以使用有点像:

 const Char[] splitChars = new Char[] {'|'}; string[] splitData = data.Split(splitChars, StringSplitOptions.RemoveEmptyEntries) 

我可能在这里有错误的想法,但你只想用’|’分割data字符串 字符作为分隔符? 在那种情况下,你可以:

 string[] result = data.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries).Select(d => d.Trim()).ToArray(); 

这将返回所有字段,不带空格并删除空字段。 您可以在“ Select部分中根据需要对结果进行格式化,例如

 .Select(d => "[" + d.Trim() + "]").ToArray(); 

根据@Jaroslav Jandek的好答案,我写了一个extension method ,我把它放在这里,也许它可以节省你的时间。

 ///  /// String.Split with RemoveEmptyEntries option for clean up empty entries from result ///  /// Value to parse /// The separator /// Hint: pass -1 to get Last item /// Get array of split value ///  public static object CleanSplit(this string s, char separator, int index, bool wholeResult = false) { if (string.IsNullOrWhiteSpace(s)) return ""; var split = s.Split(new char[] { separator }, StringSplitOptions.RemoveEmptyEntries); if (wholeResult) return split; if (index == -1) return split.Last(); if (split[index] != null) return split[index]; return ""; } 

1.如何删除空结果?

您可以使用LINQ删除所有等于string.Empty的条目:

 string[] columns = lineSplitter.Split(data); columns = columns.ToList().RemoveAll(c => c.Equals(string.Empty)).ToArray(); 

2.如何拆除最后一根管子?

您可以在此处使用LINQ删除所有与要删除的字符相等的条目:

 columns = columns.ToList().RemoveAll(c => c.Equals("|")).ToArray(); 

这个怎么样:

假设我们有一条线:

 line1="|* 9070183020 |04.02.2011 |107222 |M/S SUNNY MEDICOS |GHAZIABAD | 32,768.00 |"; 

我们可以得到所需的结果:

 string[] columns =Regex.Split(line1,"|"); foreach (string c in columns) c=c.Replace("*","").Trim(); 

这将得到以下结果:

 [9070183020] [04.02.2011] [107222] [M/S SUNNY MEDICOS] [GHAZIABAD] [32,768.00] 

使用此解决方案:

 string stringwithDelemeterNoEmptyValues= string.Join(",", stringwithDelemeterWithEmptyValues.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));