转义字符的最佳方式
我需要通过在\\
之前转义这些字符:+-&|!(){}[]^"~*?:\
。 这是做什么最好的方法。我的第一个想法是使用替换,但是它会搜索字符串来替换每个项目。 我在想一定有办法用正则表达式来做到这一点。转义字符的最佳方式
有可能使用正则表达式。最棘手的部分是正确转义特殊字符没有进入反斜杠地狱:
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为字符串生成器解决方案 – Jamiec
如果字符串完全使用StringBuilder构造函数,它允许您提供初始大小并将其设置为稍大于原始字符串。 –
确实使用正则表达式(Regex)来做到这一点的最好方法!
string str = @"+-&|!(){}[]^""~*?:\";
string pattern = @"(\+|\-|\&|\||\!|\(|\)|\{|\}|\[|\]|\^|\""|\~|\*|\?|\:|\\)";
string output = Regex.Replace(str, pattern, @"\$1");
提供了以下的输出:
\+\-\&\|\!\(\)\{\}\[\]\^\"\~\*\?\:\\
为什么? RegEx很方便,但速度可能很慢。实际上,.NET 4.5中为数不多的几个特性改进之一是限制正则表达式的执行时间。 http://en.wikipedia.org/wiki/.NET_Framework_version_history#Common_Language_Runtime_.28CLR.29 –
使用一个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();
+½用于提示StringBuilder。然而,看过你的文章后,我认为它演示了一个与我的答案中的代码略有不同的方法。我认为效率不高,但不确定。另外我觉得这篇文章很难阅读。你能发布你使用的代码吗?无论如何,我将其中一个答案改为另一个问题。 :) –
@MarkByers这里是我的实施。 –
+1提供的代码。与我的代码相比,我仍然对性能表现有点担忧......我没有测试过,但我怀疑由于重复的替换,速度会变慢。而且还有一个bug,因为它首先用反斜杠转义特殊字符,然后用另一个反斜杠转义*反斜杠,我不认为这是他想要的。 –
免责声明:请阅读使用正则表达式不在其他的答案的争论这是否会导致性能问题的应用程序(例如,如果这是一个非常大的字符串,其中包含大量可变字符的实例)。但是,如果您选择正则表达式,下面将解释如何在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
字符串是在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
小问候。你对StringBuilder容量的描述不太准确。在.NET 3.5和更早版本中,容量总是2^n。因此,它与源字符串完全相同,几乎是源字符串的两倍。在4.0中,容量与源字符串相同。 (对于最小容量= 16)。 –
看到这个问题:http://stackoverflow.com/questions/323640/can-i-convert-ac-string-value-to-an-escaped-string-文字 –