我只是想知道替换必须随后替换的字符串字符的最简单方法是什么。
例如:
var str = "[Hello World]";
//enclose all occurences of [ and ] with brackets[]
str = str.Replace("[","[[]").Replace("]","[]]");
[[]Hello World[]]
[[[]]Hello World[]]
原因显然是已经修改过的字符串的第二个替换。
那么如何用包含“坏”字符的字符替换所有“坏”字符的出现?
快速衡量所有方法,发现StringBuilder是最有效的方式。
190kb文件(全部以毫秒为单位)
regexTime 40.5065 replaceTime 20.8891 stringBuilderTime 6.9776
7MB文件
regexTime 1209.3529 replaceTime 403.3985 stringBuilderTime 175.2583
顺便说一下,来自 John 的直接StringBuilder
方法的速度是 Sehe 的Aggregate方法的两倍。
我已经做了一个扩展:
public static String EncloseChars(this string input, char[] charsToEnclose, String leftSide, String rightSide) {
if (charsToEnclose == null || leftSide == null || rightSide == null)
throw new ArgumentException("Invalid arguments for EncloseChars", charsToEnclose == null ? "charsToEnclose" : leftSide == null ? "leftSide" : "rightSide");
Array.Sort(charsToEnclose);
StringBuilder sb = new StringBuilder();
foreach (char c in input) {
if (Array.BinarySearch(charsToEnclose, c) > -1)
sb.Append(leftSide).Append(c).Append(rightSide);
else
sb.Append(c);
}
return sb.ToString();
}
"[Hello World]".EncloseChars(new char[]{'[', ']'},"[","]");
答案 0 :(得分:5)
这是一种非常 uncool 的方法。但它的优势在于我非常接近万无一失,并且不使用正则表达式(如果你不想使用正则表达式)。
StringBuilder sb = new StringBuilder();
foreach (char c in str.ToCharArray()) {
if (c == '[' || c == ']') {
sb.Append('[' + c + ']');
}
else {
sb.Append(c);
}
}
string result = sb.ToString();
答案 1 :(得分:4)
怎么样:
str = str.Replace("[", "$1[$2")
.Replace("]", "$1]$2")
.Replace("$1", "[")
.Replace("$2", "]");
答案 2 :(得分:3)
这种优雅的正则表达方法怎么样:
Regex.Replace("[Hello World]", @"[\[\]]", "[$0]");
单元测试吗?
[TestMethod]
public void UnitTestThat()
{
Assert.AreEqual(@"[[]Hello World[]]", Regex.Replace("[Hello World]", @"[\[\]]", "[$0]"));
}
测试通过了
编辑@JohnMcGrant
这是一个效率稍低的代码版本,顺便提一下,与上面的正则表达式完全相同:
string result = input.Aggregate(new StringBuilder(), (a, c) =>
-1 != "[]".IndexOf(c) ? a.AppendFormat("[{0}]", c) : a.Append(c)).ToString();
答案 3 :(得分:1)
怎么样:
char[] replacedChars = str.SelectMany(ch =>
(ch == '[' ? new char[] {'[', '[', ']'} :
(ch == ']' ? new char[] {'[', ']', ']'} :
new char[] {ch}))).ToArray();
string replaced = new string(replacedChars);
请注意,这可以避免多循环问题,但创建的数组至少与输入字符串中的字符一样多,因此在性能方面可能不是最佳。
答案 4 :(得分:1)
StringBuilder result = new StringBuilder();
foreach (Char singleCharacter in str)
{
result.Append(singleCharacter.Equals('[') ? "[[]" : singleCharacter.Equals(']') ? "[]]" : singleCharacter.ToString());
}
str = result.ToString();
答案 5 :(得分:0)
我有完全相同的问题,所以我做了一个辅助函数来做那个
protected string ReplaceUsingDictionary(string subject, Dictionary<string,string> pairs)
{
StringBuilder sb = new StringBuilder(subject);
sb.Replace("{", "{{").Replace("}", "}}");
int i=0;
foreach (string key in pairs.Keys.ToArray())
{
sb.Replace(
key.Replace("{", "{{").Replace("}", "}}"),
"{" + i + "}"
);
i++;
}
return string.Format(sb.ToString(), pairs.Values.ToArray());
}
// usage
Dictionary<string, string> replacements = new Dictionary<string, string>();
replacements["["] = "[[]";
replacements["]"] = "[]]";
string mystr = ReplaceWithDictionary("[HelloWorld]", replacements); // returns [[]HelloWorld[]]