转义字符的最佳方式

本文关键字:方式 最佳 转义字符 | 更新日期: 2023-09-27 18:10:41

我需要转义这些字符:+-&|!(){}[]^"~*?:',在它们前面加一个''。最好的方法是什么?我的第一个想法是使用replace,但这将搜索字符串中要替换的每个项。我在想一定有一种方法可以用正则表达式做到这一点,可以一次通过。

转义字符的最佳方式

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

s = Regex.Replace(s, @"[+'-&|!(){}[']^""~*?:'']", "''$0");
Eric J.提到的StringBuilder解决方案简单而优雅。这里有一种编码方法:
StringBuilder sb = new StringBuilder();
foreach (char c in s)
{
    if ("+-&|!(){}[]^'"~*?:''".Contains(c))
    {
        sb.Append('''');
    }
    sb.Append(c);
}
s = sb.ToString();

使用StringBuilder可能是比regex更好的选择。这里有一个msdn的帖子来支持这个想法:Regex。替换vs字符串。Replace vs StringBuilder。替换

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();

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

对于许多应用程序来说,这并不重要。既然你问了这个问题,我想对你来说可能是这样的。

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

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

最好的方法当然是使用正则表达式(Regex) !

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

给出如下输出:

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

免责声明:如果使用regex会导致应用程序的性能问题(例如,如果这是一个非常大的字符串,包含许多可逃避字符的实例),请务必阅读其他答案中关于而不是的参数。然而,如果你选择regex,下面将解释如何在一行代码中完成它。

你要找的是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