【发布时间】:2011-12-02 13:01:43
【问题描述】:
我需要转义这些字符:+-&|!(){}[]^"~*?:\,方法是在它们前面加上 \\。
做这个的最好方式是什么。我的第一个想法是使用替换,但这会搜索每个要替换的项目的字符串。
我在想一定有一种方法可以使用正则表达式来一次性完成。
【问题讨论】:
标签: c# string escaping replace
我需要转义这些字符:+-&|!(){}[]^"~*?:\,方法是在它们前面加上 \\。
做这个的最好方式是什么。我的第一个想法是使用替换,但这会搜索每个要替换的项目的字符串。
我在想一定有一种方法可以使用正则表达式来一次性完成。
【问题讨论】:
标签: c# string escaping replace
最好的方法就是使用正则表达式(Regex)!
string str = @"+-&|!(){}[]^""~*?:\";
string pattern = @"(\+|\-|\&|\||\!|\(|\)|\{|\}|\[|\]|\^|\""|\~|\*|\?|\:|\\)";
string output = Regex.Replace(str, pattern, @"\$1");
给出以下输出:
\+\-\&\|\!\(\)\{\}\[\]\^\"\~\*\?\:\\
【讨论】:
使用 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();
【讨论】:
免责声明:请阅读其他答案中关于 not 使用正则表达式的参数,如果这会导致您的应用程序出现性能问题(例如,如果这是一个非常大的字符串,其中包含很多您的实例可转义字符)。但是,如果您选择正则表达式,下面将解释如何在 1 行代码中执行此操作。
您正在寻找的是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
【讨论】:
可以使用正则表达式。最棘手的部分是正确转义特殊字符而不进入反斜杠地狱:
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();
【讨论】:
字符串在 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
【讨论】: