C#Regex.Split:删除空结果

时间:2011-02-06 08:33:52

标签: 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

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

9 个答案:

答案 0 :(得分:41)

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一样。

您也可以使用匹配。

答案 1 :(得分:2)

我认为这可能与删除空字符串相同:

assert!(result_function().is_ok());

答案 2 :(得分: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]

答案 3 :(得分:1)

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

所以使用有点像:

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

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

答案 4 :(得分: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]

答案 5 :(得分:0)

我可能在这里有错误的想法,但您只想使用“|”拆分data字符串字符作为分隔符?在那种情况下,你可以尝试:

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

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

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

答案 6 :(得分:0)

基于@Jaroslav Jandek的好答案,我写了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 "";
}

答案 7 :(得分: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();

答案 8 :(得分:0)

使用此解决方案:

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