如何转义 JSON 字符串?
Posted
技术标签:
【中文标题】如何转义 JSON 字符串?【英文标题】:How to escape JSON string? 【发布时间】:2009-08-06 23:40:42 【问题描述】:是否有任何类/函数可用于轻松进行 JSON 转义?我宁愿不用自己写。
【问题讨论】:
JsonConvert.ToString() 为我工作。 @MartinLottering 谢谢!!!我一直在寻找一种将 json 转换为格式化字符串的方法。以下答案均无效,但确实有效。 【参考方案1】:我用System.Web.HttpUtility.javascriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
【讨论】:
我用它来避免 VS2015 中缺少System.Web.Helpers.Json.Encode
,但它需要 (input, true)
参数来包含实际的引号。
这是我缺少的链接
我注意到这会将单引号 ' 编码为 \u0027
。然而,单引号在 JSON 字符串中是有效的。【参考方案2】:
对于那些使用 Newtonsoft 非常流行的 Json.Net 项目的人来说,任务是微不足道的:
using Newtonsoft.Json;
....
var s = JsonConvert.ToString(@"a\b");
Console.WriteLine(s);
....
此代码打印:
"a\\b"
也就是说,生成的字符串值包含引号以及转义的反斜杠。
【讨论】:
我无法重现此方法来反序列化编码和转义的 unc 路径。我的路径"WatchedPath": "\\\\myserver\\output"
变成了"\"\\\\\\\\myserver\\\\output\""
,这是非常不可接受的。
上述方法不适用于反序列化 - 当您想要手动创建 JSON 文本并且您有一个 C# 字符串并且需要将其正确表示为文本时使用它。
@slestak,我想我遇到了和你一样的问题。你找到解决办法了吗?
@GP24 IIRC,我没有。抱歉,我没有更多信息。
没问题,谢谢回复。如果对您有帮助,我会这样做: yourAnnoyingDoubleEncodedString.Replace("\\\\", "\\").Replace("\\\"", "\"");【参考方案3】:
在the answer by Dejan的基础上,你可以做的是import System.Web.Helpers
.NET Framework assembly,然后使用如下函数:
static string EscapeForJson(string s)
string quoted = System.Web.Helpers.Json.Encode(s);
return quoted.Substring(1, quoted.Length - 2);
Substring
调用是必需的,因为Encode
会自动用双引号将字符串括起来。
【讨论】:
看起来 System.Web.Helpers 在 .Net 4.0 之前不可用 ……在 Visual Studio 2015 中也没有了。 这是 ASP.NET 网页 2.0 的一部分。它可以使用 NuGet 添加。它不是框架的一部分。【参考方案4】:是的,只需将以下函数添加到您的 Utils 类或其他东西中:
public static string cleanForJSON(string s)
if (s == null || s.Length == 0)
return "";
char c = '\0';
int i;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 4);
String t;
for (i = 0; i < len; i += 1)
c = s[i];
switch (c)
case '\\':
case '"':
sb.Append('\\');
sb.Append(c);
break;
case '/':
sb.Append('\\');
sb.Append(c);
break;
case '\b':
sb.Append("\\b");
break;
case '\t':
sb.Append("\\t");
break;
case '\n':
sb.Append("\\n");
break;
case '\f':
sb.Append("\\f");
break;
case '\r':
sb.Append("\\r");
break;
default:
if (c < ' ')
t = "000" + String.Format("X", c);
sb.Append("\\u" + t.Substring(t.Length - 4));
else
sb.Append(c);
break;
return sb.ToString();
【讨论】:
为什么要转义/
?
我知道这是一个旧的答案,我很高兴看到这是因为我不想依赖任何外部库,但我注意到控制字符的默认情况将总是返回“\\u000X”。我相信您需要先将 char 转换为 int。考虑将其替换为string t = "000" + ((int)c).ToString("X");
正确的默认大小写必须是:t = "000" + String.Format("0:X",(int) c);
我们真正想要的是“"\\u" + ((int)c).ToString("X4")
(虽然我觉得两个Appends会更好)【参考方案5】:
我使用以下代码来转义 json 的字符串值。 您需要将您的 '"' 添加到以下代码的输出中:
public static string EscapeStringValue(string value)
const char BACK_SLASH = '\\';
const char SLASH = '/';
const char DBL_QUOTE = '"';
var output = new StringBuilder(value.Length);
foreach (char c in value)
switch (c)
case SLASH:
output.AppendFormat("01", BACK_SLASH, SLASH);
break;
case BACK_SLASH:
output.AppendFormat("00", BACK_SLASH);
break;
case DBL_QUOTE:
output.AppendFormat("01",BACK_SLASH,DBL_QUOTE);
break;
default:
output.Append(c);
break;
return output.ToString();
【讨论】:
这真的拯救了我的一天。非常感谢! 请勿在生产环境中使用此代码!这种 JSON 转义遗漏了重要的特殊字符。见:***.com/a/33799784 这段代码没有涵盖所有的特殊情况。不要在生产中使用。 重新发明***,并在特殊情况下引入一些错误,不是一个好的答案【参考方案6】:在 .Net Core 3+ 和 .Net 5+ 中:
string escapedJsonString = JsonEncodedText.Encode(jsonString);
【讨论】:
您需要提及的是,默认情况下这不会进行微不足道的转义,结果可能比您想要的要转义得多。例如,引号、三角括号和许多字母将被转换为 unicode 字符,并且只有在您在另一端取消转义时才能使用。【参考方案7】:这里提供的方法有问题。 当您可以使用 System.Web.HttpUtility.JavaScriptEncode 时,为什么要冒险这么远?
如果你在较低的框架上,你可以从单声道复制粘贴它
感谢单一项目@ https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
public static string JavaScriptStringEncode(string value, bool addDoubleQuotes)
if (string.IsNullOrEmpty(value))
return addDoubleQuotes ? "\"\"" : string.Empty;
int len = value.Length;
bool needEncode = false;
char c;
for (int i = 0; i < len; i++)
c = value[i];
if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
needEncode = true;
break;
if (!needEncode)
return addDoubleQuotes ? "\"" + value + "\"" : value;
var sb = new System.Text.StringBuilder();
if (addDoubleQuotes)
sb.Append('"');
for (int i = 0; i < len; i++)
c = value[i];
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
sb.AppendFormat("\\u0:x4", (int)c);
else switch ((int)c)
case 8:
sb.Append("\\b");
break;
case 9:
sb.Append("\\t");
break;
case 10:
sb.Append("\\n");
break;
case 12:
sb.Append("\\f");
break;
case 13:
sb.Append("\\r");
break;
case 34:
sb.Append("\\\"");
break;
case 92:
sb.Append("\\\\");
break;
default:
sb.Append(c);
break;
if (addDoubleQuotes)
sb.Append('"');
return sb.ToString();
这可以压缩成
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
public class SimpleJSON
private static bool NeedEscape(string src, int i)
char c = src[i];
return c < 32 || c == '"' || c == '\\'
// Broken lead surrogate
|| (c >= '\uD800' && c <= '\uDBFF' &&
(i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
// Broken tail surrogate
|| (c >= '\uDC00' && c <= '\uDFFF' &&
(i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
// To produce valid JavaScript
|| c == '\u2028' || c == '\u2029'
// Escape "</" for <script> tags
|| (c == '/' && i > 0 && src[i - 1] == '<');
public static string EscapeString(string src)
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int start = 0;
for (int i = 0; i < src.Length; i++)
if (NeedEscape(src, i))
sb.Append(src, start, i - start);
switch (src[i])
case '\b': sb.Append("\\b"); break;
case '\f': sb.Append("\\f"); break;
case '\n': sb.Append("\\n"); break;
case '\r': sb.Append("\\r"); break;
case '\t': sb.Append("\\t"); break;
case '\"': sb.Append("\\\""); break;
case '\\': sb.Append("\\\\"); break;
case '/': sb.Append("\\/"); break;
default:
sb.Append("\\u");
sb.Append(((int)src[i]).ToString("x04"));
break;
start = i + 1;
sb.Append(src, start, src.Length - start);
return sb.ToString();
【讨论】:
这也将转义三角括号。对于 html 中的 JS 很重要,但对于 JSON 编码本身并不重要。【参考方案8】:我还建议使用提到的JSON.NET 库,但如果您必须在生成的 JSON 字符串中转义 unicode 字符(例如 \uXXXX 格式),您可能必须自己做。以Converting Unicode strings to escaped ascii string 为例。
【讨论】:
【参考方案9】:我针对长字符串和短字符串对其中一些答案进行了速度测试。 Clive Paterson 的code 赢了很多,大概是因为其他人正在考虑序列化选项。这是我的结果:
Apple Banana
System.Web.HttpUtility.JavaScriptStringEncode: 140ms
System.Web.Helpers.Json.Encode: 326ms
Newtonsoft.Json.JsonConvert.ToString: 230ms
Clive Paterson: 108ms
\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\"things\to\escape\some\long\path\with\lots"\of\things\to\escape
System.Web.HttpUtility.JavaScriptStringEncode: 2849ms
System.Web.Helpers.Json.Encode: 3300ms
Newtonsoft.Json.JsonConvert.ToString: 2827ms
Clive Paterson: 1173ms
这里是测试代码:
public static void Main(string[] args)
var testStr1 = "Apple Banana";
var testStr2 = @"\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\""things\to\escape\some\long\path\with\lots""\of\things\to\escape";
foreach (var testStr in new[] testStr1, testStr2 )
var results = new Dictionary<string,List<long>>();
for (var n = 0; n < 10; n++)
var count = 1000 * 1000;
var sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
var s = System.Web.HttpUtility.JavaScriptStringEncode(testStr);
var t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.HttpUtility.JavaScriptStringEncode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
var s = System.Web.Helpers.Json.Encode(testStr);
t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.Helpers.Json.Encode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
var s = Newtonsoft.Json.JsonConvert.ToString(testStr);
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Newtonsoft.Json.JsonConvert.ToString").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
var s = cleanForJSON(testStr);
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Clive Paterson").Add(t);
Console.WriteLine(testStr);
foreach (var result in results)
Console.WriteLine(result.Key + ": " + Math.Round(result.Value.Skip(1).Average()) + "ms");
Console.WriteLine();
Console.ReadLine();
【讨论】:
【参考方案10】:我很好的单线,像其他人一样使用 JsonConvert,但添加了子字符串以删除添加的引号和反斜杠。
var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);
【讨论】:
我认为你的意思是 var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length); - 否则你从字符串的末尾砍掉 2 个字符。请记住,\" 是原始长度的附加字符。【参考方案11】:System.Web.Helpers.Json.Encode(...) 怎么样(见http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111).aspx)?
【讨论】:
【参考方案12】:String.Format("X", c);
那只是输出:X
试试这个:
string t = ((int)c).ToString("X");
sb.Append("\\u" + t.PadLeft(4, '0'));
【讨论】:
【参考方案13】:Codeplex 有一个 Json 库
【讨论】:
【参考方案14】:我选择使用System.Web.Script.Serialization.JavaScriptSerializer
。
我有一个小的静态助手类,定义如下:
internal static partial class Serialization
static JavaScriptSerializer serializer;
static Serialization()
serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
public static string ToJSON<T>(T obj)
return serializer.Serialize(obj);
public static T FromJSON<T>(string data)
if (Common.IsEmpty(data))
return default(T);
else
return serializer.Deserialize<T>(data);
序列化任何我调用Serialization.ToJSON(itemToSerialize)
的东西
要反序列化,我只需调用Serialization.FromJSON<T>(jsonValueOfTypeT)
【讨论】:
以上是关于如何转义 JSON 字符串?的主要内容,如果未能解决你的问题,请参考以下文章
Java:JSON字符串在Java中已经转义过了,如何再拼接函数呢