代码之家  ›  专栏  ›  技术社区  ›  weismat

删除空字符串

  •  1
  • weismat  · 技术社区  · 17 年前

    我已经编写了下面的正则表达式,希望自动删除空字符串,但找不到任何与regex的RemoveEmptyEntries等效的方法,我只在string中的Split方法中找到了RemoveEmptyEntries。

    string test = "{ key1 = { key2= xx } | key3 = y | key4 = z }";
    string[] help = Regex.Split(test, "(=)|({)|(})|(\\|)");
    

    结果字符串数组包含空元素。我希望运行正则表达式时不会产生结果中包含的任何空字符串。

    我将非常、非常频繁地运行这段代码——因此我需要尽可能高效地运行它。 更新:因为这是一个解析器,所以我需要保留令牌,并且我发现只有一种方法可以使用Regex来保留它们。

    7 回复  |  直到 14 年前
        1
  •  4
  •   Joel Coehoorn    17 年前

    我不认为这个选项内置于正则表达式中。但是有了C#3.0,你只需要使用一个简单的 .Where()

    string[] help = Regex.Split(test, "(=)|({)|(})|(\\|)")
                         .Where(s => !string.IsNullOrEmpty(s)).ToArray();
    

    为了提高效率,只需声明一次正则表达式——可能是在类级别,也可能是静态的——而不是一直重新创建它。此外,您可能只使用返回的数组来迭代结果。您可以通过跳过 .ToArray() 在最后调用,只为迭代保留IEnumerable。

    //earlier
    RegEx KeySplitter = new RegEx ("(=)|({)|(})|(\\|)");
    

    .

    //later
    string test = ""; // 
    for (string key in KeySplitter.Split(test).Where(s => !string.IsNullOrEmpty(s)))
    {
        // ...
    }
    

    .Split 后果 ,因为 GetEnumerator 中的方法 Where .Select() 呼叫

        2
  •  2
  •   Tomalak    17 年前

    the original regex:    (=)|({)|(})|(\|)
    is equivalent to:      (=|{|}|\|)
    is equivalent to:      ([={}|])
    

    以上所有表达式返回相同的21个元素,但它们的执行方式不同。我设置了一个快速测试,该测试的迭代次数超过100000次 Split() 使用带有 RegexOptions.Compiled 和 Stopwatch 班

    • regex#1在我的硬件上需要200毫秒
    • 正则表达式2需要1691ms
    • 正则表达式3需要1542ms
    • regex#4需要1839ms(如下所示)

    YMMV。

    但是,所需的元素仍然可以被空白包围。我想这也是不需要的,所以我要拆分的正则表达式是:

    \s*([={}|])\s*
    

    返回的元素包括:

    ["", "{", "key1", "=", "", "{", "key2", "=", "xx", "}", "", "|", "key3", "=", "y", "|", "key4", "=", "z", "}", ""]
    

    在迭代数组时,剩下的几个空字符串在性能方面不应该造成大问题,并且在遇到它们时可以处理(读取:忽略)。

    编辑:如果您测量性能,您可能会发现 ([={}|]) 而且“手动”修剪数组元素比在上拆分要快 \s*([={}|])\s*

        3
  •  1
  •   Sebastian Mach    17 年前

    至于效率:如果幸运的话,你可以通过编译正则表达式获得一些性能:

    Regex r = new Regex ("<regex goes here>", RegexOptions.Compiled);
    
        4
  •  1
  •   Binoj Antony    17 年前

    要从字符串中删除空格,只需执行以下操作

    Regex exp = new Regex(@"\s+");
    string test = "{ key1 = { key2= xx } | key3 = y | key4 = z }";
    string result = test.Replace(exp, string.Empty);
    

    或者您也可以执行以下操作(未测试哪一个运行得更快)

    Regex.Replace(test, " ", string.Empty, RegexOptions.Compiled)
    

    say about compiled regex )

    在此之后,您可以使用分割代码将键放入字符串数组。

        5
  •  0
  •   Fernando Briano    17 年前

        6
  •  0
  •   lexx    17 年前

    您可以修改正则表达式并返回匹配集合,而不是使用正则表达式拆分字符串。大概是这样的:

    string test = "{ key1 = { key2= xx } | key3 = y | key4 = z }";
    
    Regex regex = new Regex("[={}|]|[^\\s={}|]{1,}");
    MatchCollection matches = regex.Matches(test);
    
    string[] help = new string[matches.Count];
    
    for (int index = 0; index < matches.Count; index++)
    {
        help[index] = matches[index].Value;                
    }
    

    这将返回与正则表达式减去最终数组中的空(空白)元素相同的结果。

        7
  •  0
  •   Svante    17 年前

    因此,您希望值之间多次出现的分隔符只匹配一次。

    \s*[{}=|][\s{}=|]*
    

    这应该按照这个顺序匹配任意数量的空格、一个分隔符以及任意数量的空格和其他分隔符。

    添加C#字符串转义和编译声明:

    Regex regex = new Regex("\\s*[{}=|][\\s{}=|]*");