String。放置更多后续字符

问题描述 投票:0回答:5

最近我使用了String.Replace方法来确保用户输入(后来包含在HTML注释中)被正确清理。我需要输入以供以后使用,所以HttpUtility.HtmlEncode不是一个选择。

我的代码所做的是在输入上调用String.Replace(“ - ”,“ - - ”)。但是,我意识到Replace函数没有像我预期的那样运行。例如:

var userData = "----";
return userData.Replace("--", "- -"); // returns "- -- -", I expected "- - - -"

要么:

var userData = "---";
return userData.Replace("--", "- -"); // returns "- --", I expected "- - -"

在第二个示例中,您可以看到,此清理无用,恶意用户实际上仍可以结束注释。

现在我的问题:

  1. 这被认为是String.Replace的预期行为吗?
  2. 我可以轻松实现我打算实现的输出吗?

注意:我知道还有其他方法可以清理输出(例如,用下划线替换连字符),但我对这种特殊方式感兴趣(即后续破折号之间的空格)。

c# .net string
5个回答
4
投票

这是预期的行为,因为你对Replace的调用仅在字符串上进行一次传递。因此,你的字符串中的每个“ - ”实例都被“ - - ”代替,每个实例都相互邻接,例如, “ - - ”旁边的“ - - ”旁边的“ - - ”等等,看起来像这样:“ - - | - - | - - ”( -

只需再次运行替换以清除第一次替换产生的邻接“ - ”字符:

var result = userData.Replace("--", "- -").Replace("--", "- -"); 

我还想指出,虽然对于小例子这种类型的直接字符串操作很好,但是如果要将其扩展为更大或更多的迭代字符串操作,您可能需要考虑使用System.Text.StringBuilder。每次修改string(即通过连接,追加或调用Replace)时,都会在内存中创建一个新字符串,因为字符串是不可变的。另一方面,StringBuilder通过使用可变的字符集来解决这个问题,并且当你调用string时最后只产生一个ToString

以下是你如何使用StringBuilder做同样的事情

var sb = new System.Text.StringBuilder(userData);
var result = sb.Replace("--", "- -").Replace("--", "- -").ToString(); 

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


0
投票

string.Replace做了一个通过字符串。为了实现你的期望,做

while(userData.Contains("--"))
{
     userData = userData.Replace("--", "- -");
}

0
投票

也许这可能有用:

var userData = "----";
userData = Regex.Replace(userData, @"-{1}", " -").TrimStart();

0
投票
  1. String.Replace做你想要的一次。 (返回一个新字符串,其中当前实例中所有出现的指定字符串都被另一个指定的字符串替换。)reference
  2. 我会这样做的, 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, "- - -"); } }
© www.soinside.com 2019 - 2024. All rights reserved.