2011-02-06 95 views
24

我对其中进口数千行的应用,其中每行有这样的格式工作: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.如何取下最后一根管子?

感谢您的任何帮助。
Regards,
Yogesh。

编辑:
我觉得我的问题有点误解。这从来没有关于我怎么能做到这一点。这只是大约我怎么能通过更改Regex在上面的代码

我知道我可以在很多方面做到这一点。我已经与具有Where子句和与这也是一种替代方法(两次以上)上述代码进行更快:

Regex regex = new Regex(@"(^\|\*\s*)|(\s*\|\s*)"); 
data = regex.Replace(data, "|"); 

string[] columns = data.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); 

其次,作为测试的情况下,我的系统可以解析92K +这样线在原始方法中少于1.5秒,而在第二种方法中少于700毫秒,在这里我永远不会发现超过几千的实际情况,所以我不认为我需要在这里考虑速度。在我看来,在这种情况下考虑速度是不成熟的优化。

我已经找到了答案,我的第一个问题:它不能与Split来完成,因为是建立在没有这样的选择

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

+0

要回答你的第一个问题,我相信正则表达式的分组部分应该是`@“(。+?)”`。否则就可能匹配空白(这是你现在拥有的)。 – 2011-02-06 08:38:14

+0

在这种情况下,杰夫很难处理。它会给出完全相同的结果。 – Yogesh 2011-02-06 08:41:24

+0

就像你提到成千上万的条目一样:使用String.Split然后再做一些String处理比使用正则表达式要快得多。 – Foxfire 2011-02-06 11:57:21

回答

37
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。

您也可以使用匹配。

0

如何:

假设我们有一个行:

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] 
0

我可能会有ng想法在这里,但你只是想分割data字符串使用'|'字符作为分隔符?在这种情况下,您可以尝试:

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

这将返回所有字段,不带空格并删除空字段。您可以在Select部分中按自己喜欢的方式设置格式,例如

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

作为替代分裂,它总是会引起麻烦,当你的分隔符也存在在输入的开头和结尾,你可以尝试在管道中的匹配内容:

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] 
0

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

所以使用有点像:

const Char[] splitChars = new Char[] {'|'}; 

string[] splitData = data.Split(splitChars, StringSplitOptions.RemoveEmptyEntries) 
2

我觉得这可能是一个等效努力消除空字符串:

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

基于@Jaroslav扬德克的伟大的答案,我写了一个extension method,我把它放在这里,也许它可以节省你的时间。

/// <summary> 
/// String.Split with RemoveEmptyEntries option for clean up empty entries from result 
/// </summary> 
/// <param name="s">Value to parse</param> 
/// <param name="separator">The separator</param> 
/// <param name="index">Hint: pass -1 to get Last item</param> 
/// <param name="wholeResult">Get array of split value</param> 
/// <returns></returns> 
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 ""; 
} 
0

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(); 
0

使用此解决方案:

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