字符串.替换更多出现的后续字符
本文关键字:字符 替换 字符串 | 更新日期: 2023-09-27 18:27:10
最近我使用了String.Replace方法来确保后来包含在HTML注释中的用户输入得到正确的净化。我需要这个输入供以后使用,所以HttpUtility.HtmlEncode不是一个选择。
我的代码对输入调用String.Replace("--","--")。然而,我意识到Replace函数的行为并不像我预期的那样。例如:
var userData = "----";
return userData.Replace("--", "- -"); // returns "- -- -", I expected "- - - -"
或:
var userData = "---";
return userData.Replace("--", "- -"); // returns "- --", I expected "- - -"
在第二个例子中,您可以看到,这种净化是无用的,恶意用户实际上仍然可以结束评论。
现在我的问题是:
- 这是否被认为是String.Replace的预期行为
- 我能轻松实现我想要实现的输出吗
注意:我知道还有其他方法可以净化输出(例如,用下划线替换连字符),但我对这种特殊的方式感兴趣(即,后面的短划线之间的空格)。
这是预期的行为,因为对Replace
的调用只对字符串进行一次传递。因此,字符串中"-"的每个实例都被"-"替换,每个实例都相互邻接,例如"-"旁边的"-","-"后面的"--"等等,看起来像这样:"-|-|-"(为了清晰起见,添加了<--垂直线)。
只需第二次运行替换即可清除第一次替换产生的相邻"-"字符:
var result = userData.Replace("--", "- -").Replace("--", "- -");
我还想指出,虽然对于小示例来说,这种类型的直接字符串操作是可以的,但如果要将其扩展到更大或更迭代的字符串操作,则需要考虑使用 以下是如何用System.Text.StringBuilder
。每次修改string
(即通过连接、追加或调用Replace
)时,都会在内存中创建一个新的字符串,因为字符串是不可变的StringBuilder
做同样的事情var sb = new System.Text.StringBuilder(userData);
var result = sb.Replace("--", "- -").Replace("--", "- -").ToString();
您是否考虑过使用RegEx
?有一种RegEx.Replace()
方法,您可以使用适当的RegEx
模式处理不同的变化和出现
https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.replace(v=vs.110).aspx
RegEx.Replace(stringToReplaceAndTest,"/-/g"," -");
此RegEx将全局查找短划线,并将其替换为和空白+短划线。。。但就像我说的,你只需要找到正确的模式。。。HTH
string.Replace
执行一次字符串传递。为了达到你的期望,做
while(userData.Contains("--"))
{
userData = userData.Replace("--", "- -");
}
也许这会很有用:
var userData = "----";
userData = Regex.Replace(userData, @"-{1}", " -").TrimStart();
-
字符串。替换只执行一次您想要的操作。(返回一个新字符串,其中当前实例中指定字符串的所有出现都被另一个指定字符串替换。)引用
-
我愿意,
public static class StringExtensions { public static string ReplaceAllOccurrences( this string str, string oldValue, string newValue) { var result = str; while (result.Contains(oldValue)) { result = result.Replace(oldValue, newValue); } return result; } } [TestClass] public class ReplaceAllOccurencesTest { [TestMethod] public void Test() { var userData = "----"; var replaced = userData.ReplaceAllOccurrences("--", "- -"); // returns "- -- -", I expected "- - - -" Assert.AreEqual(replaced, "- - - -"); userData = "---"; replaced = userData.ReplaceAllOccurrences("--", "- -"); // returns "- --", I expected "- - -" Assert.AreEqual(replaced, "- - -"); } }