我已经编写了以下正则表达式,并希望自动删除空字符串,并且找不到任何与Regex相同的RemoveEmptyEntries,我只在字符串中找到了Split方法。
string test = "{ key1 = { key2= xx } | key3 = y | key4 = z }";
string[] help = Regex.Split(test, "(=)|({)|(})|(\\|)");
结果字符串数组包含空的元素。我想运行正则表达式而不会产生结果中包含的任何空字符串。
我将非常频繁地运行此代码 - 因此我需要尽可能高效。 更新:由于这是一个解析器,我需要保留令牌,我发现只有一种方法可以让Regex保留它们。
答案 0 :(得分:4)
我不认为该选项是内置于RegEx中的。但是使用C#3.0,您可以使用简单的.Where()
:
string[] help = Regex.Split(test, "(=)|({)|(})|(\\|)")
.Where(s => !string.IsNullOrEmpty(s)).ToArray();
为了提高效率,请将RegEx声明一次 - 可能在类级别或将其设置为静态 - 而不是一直重新创建它。此外,你只是使用返回的数组来迭代结果。您可以通过跳过最后的.ToArray()
调用并保持IEnumerable进行迭代来加快速度。
//earlier
RegEx KeySplitter = new RegEx ("(=)|({)|(})|(\\|)");
//later
string test = ""; //
for (string key in KeySplitter.Split(test).Where(s => !string.IsNullOrEmpty(s)))
{
// ...
}
关于linq-to-objects如何工作的一个好处是,它仍然只会迭代.Split
结果一次,因为GetEnumerator
方法中的Where
方法.Select()
函数会做懒惰的评估。根据您在for循环中需要执行的操作,您可以通过添加{{1}}调用来获得类似的效率。
答案 1 :(得分:2)
可能不是问题的完整解决方案,但我对手头的问题有一些评论(标记字符串):
the original regex: (=)|({)|(})|(\|)
is equivalent to: (=|{|}|\|)
is equivalent to: ([={}|])
所有上述表达式都返回相同的21个元素,但它们的表现不同。我使用带有Split()
和RegexOptions.Compiled
类的预构建Regex对象,设置了超过100,000次Stopwatch
次操作的快速测试。
因人而异。
但是,所需的元素仍然可以被空白区域包围。我认为这也是不受欢迎的,所以我将拆分的正则表达式是:
\s*([={}|])\s*
返回的元素是:
["", "{", "key1", "=", "", "{", "key2", "=", "xx", "}", "", "|", "key3", "=", "y", "|", "key4", "=", "z", "}", ""]
在迭代数组时,少数剩余的空字符串在性能方面不会造成大问题,并且在遇到它们时可以处理(读取:忽略)。
编辑:如果你测量性能,你可能会发现([={}|])
上的分裂并且“手动”修剪数组元素比分割\s*([={}|])\s*
更快。试试对你有用的东西。
答案 2 :(得分:1)
关于效率:如果明星很幸运,你可以通过编译正则表达式获得一些表现:
Regex r = new Regex ("<regex goes here>", RegexOptions.Compiled);
答案 3 :(得分:1)
要从字符串中删除空格,只需执行此操作
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)
以下是Jeff Atwood(顺便提一下StackOverFlow的创建者之一say about compiled regex)
在此之后,您可以使用拆分代码将密钥放入字符串数组中。
答案 4 :(得分:0)
我没有弄明白你的问题。但是“^ $”意味着一条线在它开始的地方结束,因此是一条空行。这有帮助吗?
答案 5 :(得分:0)
您可以修改正则表达式并返回匹配集合,而不是使用正则表达式拆分字符串。像这样:
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;
}
这将返回与正则表达式相同的减去最终数组中的空(空格)元素。
答案 6 :(得分:0)
因此,您希望值之间多次出现的分隔符只能匹配一次。
\s*[{}=|][\s{}=|]*
这应该按此顺序匹配任何数量的空格,一个分隔符,以及任何数量的空白和进一步的分隔符。
添加C#字符串转义和编译声明:
Regex regex = new Regex("\\s*[{}=|][\\s{}=|]*");