逃避角色的最佳方式

时间:2011-10-06 19:51:14

标签: c# string escaping replace

我需要通过在+-&|!(){}[]^"~*?:\前加上这些字符:\\。 做这个的最好方式是什么。我的第一个想法是使用替换,但是会搜索字符串以替换每个项目。 我认为必须有一种方法可以使用正则表达式来完成所有这一切。

5 个答案:

答案 0 :(得分:6)

可以使用正则表达式。最棘手的部分是正确地逃避特殊字符而不会陷入反斜杠地狱:

s = Regex.Replace(s, @"[+\-&|!(){}[\]^""~*?:\\]", "\\$0");

StringBuilder解决方案mentioned by Eric J.简单而优雅。这是编码的一种方法:

StringBuilder sb = new StringBuilder();
foreach (char c in s)
{
    if ("+-&|!(){}[]^\"~*?:\\".Contains(c))
    {
        sb.Append('\\');
    }
    sb.Append(c);
}
s = sb.ToString();

答案 1 :(得分:4)

使用StringBuilder可能比正则表达式更好。这是一个支持这个想法的msdn帖子:Regex.Replace vs String.Replace vs StringBuilder.Replace

public const string CharsToBeEscaped = "+-&|!(){}[]^\"~*?:\\'";

string s = "+-&|!(){}[]^\"~*?:\\";

StringBuilder sb = new StringBuilder();
sb.Append( s );

for ( int i = 0; i < CharsToBeEscaped.Length; i++ ) {
    sb.Replace( CharsToBeEscaped.Substring(i,1), @"\" + CharsToBeEscaped[i] );
}
sb.Replace( @"\\", @"\" );

s = sb.ToString();

答案 2 :(得分:1)

字符串在C#中是不可变的,这意味着每个string.Replace()都会创建一个新的原始字符串的修改副本。

对于许多真正无关紧要的应用程序。但是,既然你在询问它,我认为可能就在你的情况下。

最有效的方法可能是使用StringBuilder来构建修改后的字符串。循环遍历源字符串一次,并在每个字符串位置附加字符,或者在适用的情况下附加转义版本。使用预先分配初始内部缓冲区大小的StringBuilder constructor略大于源字符串。

大多数其他答案提到的RegEx对于这个特定的应用程序可能也会非常有效,并且涉及的代码更少。但是,由于RegEx必须固有地应用通用解析逻辑,因此它不能像针对您的特定需求的解决方案那样快。此外,在某些情况下(可能不是这一个)RegEx可能非常慢。参见

http://en.wikipedia.org/wiki/.NET_Framework_version_history#Common_Language_Runtime_.28CLR.29

http://www.codinghorror.com/blog/2006/01/regex-performance.html

答案 3 :(得分:0)

确保使用正则表达式(Regex)的最佳方法!

string str = @"+-&|!(){}[]^""~*?:\";
string pattern = @"(\+|\-|\&|\||\!|\(|\)|\{|\}|\[|\]|\^|\""|\~|\*|\?|\:|\\)";
string output = Regex.Replace(str, pattern, @"\$1");

提供以下输出:

\+\-\&\|\!\(\)\{\}\[\]\^\"\~\*\?\:\\

答案 4 :(得分:0)

DIsclaimer:如果这会导致应用程序出现性能问题,请阅读其他使用正则表达式的 not 的答案中的参数(例如,如果这是一个包含大量实例的非常大的字符串逃避的角色)。但是,如果您选择正则表达式,则下面将解释如何在一行代码中执行此操作。

您正在寻找的Regex.Replace。您提供了一个正在搜索的正则表达式,输入和每个匹配运行的MatchEvaluator。在您的情况下,您只需返回String.Concat(@"\",match.Value)

这样的事情(input是你的字符串):

var replaced = Regex.Replace(input, //your string
         @"[\+\-&|!]", // partial regex to give you an idea
         match => String.Concat(@"\",match.Value)); //MatchEvaluator, runs for each capture