最近我使用了String.Replace方法来确保用户输入(后来包含在HTML注释中)被正确清理。我需要输入供以后使用,所以HttpUtility.HtmlEncode不是一个选择。
我的代码所做的是在输入上调用String.Replace(“ - ”,“ - - ”)。但是,我意识到Replace函数没有像我预期的那样运行。例如:
var userData = "----";
return userData.Replace("--", "- -"); // returns "- -- -", I expected "- - - -"
或:
var userData = "---";
return userData.Replace("--", "- -"); // returns "- --", I expected "- - -"
在第二个示例中,您可以看到,此清理无用,恶意用户实际上仍然可以结束评论。
现在我的问题:
注意:我知道还有其他方法可以清理输出(例如,用下划线替换连字符),但我对这种特殊方式感兴趣(即后续破折号之间的空格)。
答案 0 :(得分:4)
这是预期的行为,因为您对Replace
的调用仅对字符串进行一次传递。因此,每一个" - "在你的字符串中被" - - "取代,每一个都相互邻接,例如" - - "旁边" - - "旁边" - - "等等,看起来像这样:" - - | - - | - - " (< - 为清晰起见添加了垂直线)。
再次运行更换以清理对接" - "第一次替换产生的字符:
var result = userData.Replace("--", "- -").Replace("--", "- -");
我还想指出,虽然对于小例子这种类型的直接字符串操作很好,如果要将其扩展为更大或更多的迭代字符串,您可能需要考虑使用System.Text.StringBuilder
操纵。每次修改string
(即通过连接,追加或调用Replace
)时,都会在内存中创建 new 字符串,因为字符串不可变。另一方面,StringBuilder
通过使用可变字符集来解决此问题,并且当您调用string
时最后只生成ToString
。
以下是使用StringBuilder
var sb = new System.Text.StringBuilder(userData);
var result = sb.Replace("--", "- -").Replace("--", "- -").ToString();
答案 1 :(得分:1)
您是否考虑过使用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
答案 2 :(得分:0)
string.Replace
会传递一个字符串。为了达到你的期望,做到
while(userData.Contains("--"))
{
userData = userData.Replace("--", "- -");
}
答案 3 :(得分:0)
String.Replace做你想做的一次。 (返回一个新字符串,其中当前实例中所有出现的指定字符串都被另一个指定的字符串替换。)reference
我会这样做,
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, "- - -");
}
}
答案 4 :(得分:0)
这可能有用:
var userData = "----";
userData = Regex.Replace(userData, @"-{1}", " -").TrimStart();