出于好奇 - 是不是有更好的执行方法来替换此字符串?
Posted
技术标签:
【中文标题】出于好奇 - 是不是有更好的执行方法来替换此字符串?【英文标题】:Out of curiosity - is there a better performing approach to do this string replace?出于好奇 - 是否有更好的执行方法来替换此字符串? 【发布时间】:2011-06-23 09:42:22 【问题描述】:我有以下方法,我需要检查一些在任何情况下都可能存在的特定字符串,然后将它们删除。只是想知道是否有更好的执行方式?
private void MyMethod(string Filter)
//need to remove <Filter> and </Filter> case in-sensitive
var result = Filter.ToLower().Replace("<filter>","");
result = Filter.ToLower().Replace("</filter>,"");
...........................
【问题讨论】:
Regex.Replace(Filter, "</?filter>", string.empty, RegexOptions.IgnoreCase);
如果您对各种方法的性能感兴趣,SO 上有很多关于它的讨论。
它不会改变标签之间的大小写。或者这对你来说无关紧要。
ToUpper
是比ToLower
更好的选择。字符串比较和替换已针对前者进行了优化。从开发人员的角度来看,没有什么区别,所以这是一个简单的修复。
@Cody Gray - 你有任何链接可以验证这一点吗?我想知道为什么这会有所不同。
@Øyvind:其实是ToUpperInvariant
。这是有道理的;无论如何,这就是您应该使用的。这里有一些链接:***.com/questions/9033/hidden-features-of-c#12137 和 msdn.microsoft.com/en-us/library/ms973919.aspx,特别是“字符串使用建议”
【参考方案1】:
检查这个答案:Is there an alternative to string.Replace that is case-insensitive?
您可能希望通过性能检查进行比较。使用分析器对此进行分析。这是真正了解什么是更快的唯一方法。
但老实说:性能真的很重要吗?你多久做一次?我真的看不到你经常这样做,那性能将成为一个问题......
您可以尝试Regex.Replace
,替换为不区分大小写。这不是更快。但它不区分大小写。
【讨论】:
为什么你认为正则表达式会更快?如果没有,您为什么建议尝试这样做? 我不认为他断言Regex.Replace
更快,恰恰相反。
不,我不认为 Regex.Replace 更快。但它确实做了一个不区分大小写的替换。我会更新我的答案。
我确实认为 RegEx 在某些条件下会更快。不确定这里是否是这种情况,OP 将不得不进行分析。【参考方案2】:
如果提供的代码适合您,那么这会更快:
private void MyMethod(string Filter)
//need to remove <Filter> and </Filter> case in-sensitive
var result = Filter.ToLower().Replace("</filter>","");
...........................
因为第一条语句的结果被忽略了。
【讨论】:
您缺少一个结束双引号。此外,这不会产生相同的结果。它只是删除了其中一个步骤。本质上,您的代码并没有按照上面的评论所说的那样做。 是的,但它与提供的代码做同样的事情,但速度更快,因为两个替换都是在Filter.ToLower()
上完成的。
我很难不赞成这个。我不应该也不会。但你让我笑了:)
您是正确的,因为原始代码确实产生了被丢弃的结果。然而,这很可能不是代码的意图,因为它没有多大意义。【参考方案3】:
这取决于一些事情,过滤器字符串的长度等。 所以你必须测量。
但我希望(单个!)RegEx 在这里更快。
【讨论】:
如果出于某种原因你有 50 个字符串要在这里替换怎么办。 RegEx 会不会很混乱? @Oyvind:会很快,越多越好。 我指的不是速度,而是代码的可读性。有什么办法可以让它看起来更好吗? (我现在不使用 RegEx,这就是我问的原因;)) @Oyvind:@"\<filter\>|\</filter\>"
。甚至可以将其缩短为 @"\</?filter\>"
,但 |
给出了一般模式:text1|text2|text3
,然后转义 RegEx 标记【参考方案4】:
这种方法的一个问题是它会将整个字符串变成小写,而不仅仅是进行不区分大小写的替换。
您可以使用正则表达式进行不区分大小写的匹配:
string result = Regex.Replace(
Filter,
"</?filter>",
String.Empty,
RegexOptions.IgnoreCase
);
另一种选择是使用IndexOf
方法来定位字符串,因为它可以进行不区分大小写的搜索:
string result = Filter;
int index;
while ((index = IndexOf("<filter>", StringComparison.OrdinalIgnoreCase)) != -1)
result = result.Remove(index, 8);
while ((index = IndexOf("</filter>", StringComparison.OrdinalIgnoreCase)) != -1)
result = result.Remove(index, 9);
【讨论】:
【参考方案5】:无论如何,您在这里将原始字符串小写,这可能不是一件好事?
【讨论】:
代码中的 cmets 表示其意图是执行不区分大小写的替换。我认为这就是字符串被转换为小写的原因。 @Cody Gray - 确实如此,但这里的问题是字符串中未被替换的部分,它也转换为全部小写。我认为这是 bjornars 关心的问题。 (即使这实际上是评论而不是答案)【参考方案6】:Replace
调用以 C++ 实现的非托管代码,我想这将很难被击败。
但是,我可以看到您继续使用 .ToLower()
,您可以减少到一个呼叫并保留字符串。
【讨论】:
我认为 ToLower() 的东西可能是个问题。此外,输出字符串现在是小写的。 是的,我只是在输入单词 :) @Henk 我使用了反射器-> 它调用ReplaceInternal
这是一个extern
互操作方法。以上是关于出于好奇 - 是不是有更好的执行方法来替换此字符串?的主要内容,如果未能解决你的问题,请参考以下文章