替代多个 String.Replaces [重复]
Posted
技术标签:
【中文标题】替代多个 String.Replaces [重复]【英文标题】:Alternative to multiple String.Replaces [duplicate] 【发布时间】:2012-08-13 23:52:14 【问题描述】:我的代码连续多次使用String.Replace
:
mystring = mystring.Replace("somestring", variable1);
mystring = mystring.Replace("somestring2", variable2);
mystring = mystring.Replace("somestring3", variable1);
我怀疑有更好更快的方法来做到这一点。你有什么建议?
【问题讨论】:
如果variable1
包含文本"somestring2"
,那么您的首选行为是什么?或者如果variable1
是"g2"
而mystring
是"somestrinsomestring"
,那么首选的行为是什么?
【参考方案1】:
对于“简单”的替代方案,只需使用 StringBuilder....
StringBuilder sb = new StringBuilder("11223344");
string myString =
sb
.Replace("1", string.Empty)
.Replace("2", string.Empty)
.Replace("3", string.Empty)
.ToString();
【讨论】:
这样更容易吗?我看到的唯一好处是它可以减少对 GC 的压力。 @Daniel Hilgarth 我所说的“更简单”的意思是实现起来仍然很简单,但是在 StringBuiler 上将替换链接在一起比在常规字符串上调用它“更好更快”并且不包括下面列出的一些正则表达式解决方案的复杂性。 这似乎是所提出的解决方案中可读性最强的。 如果需要设置条件就不好了 答案是 44 吗?【参考方案2】:我们是否正在设法使这更难了解正在发生的事情?
如果是这样,正则表达式是你的朋友
var replacements = new Dictionary<string,string>()
"somestring",someVariable1,
"anotherstring",someVariable2
;
var regex = new Regex(String.Join("|",replacements.Keys.Select(k => Regex.Escape(k))));
var replaced = regex.Replace(input,m => replacements[m.Value]);
直播:http://rextester.com/SXXB8348
【讨论】:
看起来不错,但是在编译正则表达式时,您需要在 dic 键周围调用Regex.Escape
。另请注意,它在技术上不会做同样的事情。它可能适用于 OP 的测试用例,但理论上,如果您有类似的情况,将“1”替换为“2”,然后将“2”替换为“3”,OP 的代码将导致每个“1”变为“3”而你的最终会导致“2”。只要您实际上没有用 OP 的示例替换之前迭代中已替换的内容,那么这将正常工作。
@Servy - 你说得很好。但是,我的第一句话应该指出,这是一种非常糟糕的多次替换方式。
@Jamiec:这有什么问题?它可能只需要读取字符串一次,只需复制字符串一次,让您轻松查找整个单词,让您对单词进行适当的大写,并让您执行转义字符串之类的操作(例如&amp;
=> &amp;
, "
=>&quot;
) 无需担心替换发生的顺序。
这(不幸的是)比多次调用 string.Replace() 慢得多。我也在寻找一种更快的方法来做到这一点;多次循环一个字符串似乎很浪费。
此 RegEx 解决方案只通过一次即可正确替换所有项目。在某些情况下(比如我的),这是唯一的选项,调用 .Replace 不起作用。为什么?考虑变量 1 部分包含字符串“somestring2”的情况。然后第二个 .Replace 最终会破坏您想要替换的第一件事,等等。【参考方案3】:
您至少可以将这些语句链接起来:
mystring = mystring.Replace("somestring", variable1)
.Replace("somestring2", variable2)
.Replace("somestring3", variable3);
【讨论】:
【参考方案4】:拨打Replace
三次不仅是一个有效的答案,它可能是首选:
RegEx 需要三个步骤:解析、执行、公式化。但是String.Replace
是硬编码的,因此在许多情况下它具有出色的速度。复杂的 RegEx 不如格式良好的 Replace
语句链具有可读性。 (比较Jonathan的解决方案和Daniel的解决方案)
如果您仍然不相信Replace
更适合您的情况,那就来一场比赛吧!并排尝试这两种方法并使用Stopwatch
来查看您在使用数据时节省了多少毫秒。
但是DON'T optimize prematurely!任何开发人员都更喜欢可读性和可维护性,而不是执行速度***毫秒的神秘意大利面条。
【讨论】:
【参考方案5】:这篇文章Regex: replace multiple strings in a single pass with C#可能会有所帮助:
static string MultipleReplace(string text, Dictionary replacements)
return Regex.Replace(text,
"(" + String.Join("|", adict.Keys.ToArray()) + ")",
delegate(Match m) return replacements[m.Value];
);
// somewhere else in code
string temp = "Jonathan Smith is a developer";
adict.Add("Jonathan", "David");
adict.Add("Smith", "Seruyange");
string rep = MultipleReplace(temp, adict);
【讨论】:
这与 Jamiec 的回答基本相同,但没有(必需的)转义。【参考方案6】:取决于您的数据的组织方式(您要替换的内容)或您拥有的数据数量;数组和循环可能是个好方法。
string[] replaceThese = "1", "2", "3";
string data = "replace1allthe2numbers3";
foreach (string curr in replaceThese)
data = data.Replace(curr, string.Empty);
【讨论】:
【参考方案7】:如果您不想使用 RegEx,请将此类添加到您的项目中, 它使用扩展方法“MultipleReplace”:
public static class StringExtender
public static string MultipleReplace(this string text, Dictionary<string, string> replacements)
string retVal = text;
foreach (string textToReplace in replacements.Keys)
retVal = retVal.Replace(textToReplace, replacements[textToReplace]);
return retVal;
那么你就可以使用这段代码了:
string mystring = "foobar";
Dictionary<string, string> stringsToReplace = new Dictionary<string,string>();
stringsToReplace.Add("somestring", variable1);
stringsToReplace.Add("somestring2", variable2);
stringsToReplace.Add("somestring3", variable1);
mystring = mystring.MultipleReplace(stringsToReplace);
【讨论】:
赞成这个。它允许您从数据表中构建过滤器,这非常有用。所以当你有很多过滤器(在我的例子中是 50 个)并且你有 1k 个句子要通过时,这就是猫的喵喵声。【参考方案8】:我首选的方法是使用Regex
的强大功能来解决多重替换问题。这种方法的唯一问题是您只能选择一个 string
来替换。
以下内容会将所有'/'
或':'
替换为'-'
以生成有效的文件名。
Regex.Replace("invalid:file/name.txt", @"[/:]", "-");
【讨论】:
以上是关于替代多个 String.Replaces [重复]的主要内容,如果未能解决你的问题,请参考以下文章