如何在c#中反转义多字节unicode



以下来自文本文件的unicode字符串使用3个字节编码单个省号:

u00e2 u0080 u0099s工作

这应该解码为:

工作的

我如何在c#中解码这个字符串?

例如,当我尝试以下代码:

string test = @"Itu00e2u0080u0099s working";
string test2 = System.Text.RegularExpressions.Regex.Unescape(test);

它错误地只解码第一个字节:

Ita u0080 u0099s很棒的

这是UTF8。尝试UTF8编码

using System.Text;
using System.Text.RegularExpressions;
string test = "Itu00e2u0080u0099s working";
byte[] bytes = Encoding.GetEncoding(28591)
.GetBytes(test);
var converted = Encoding.UTF8.GetString(bytes);//It’s working

尝试解析文件:

private static Regex _regex = new Regex(@"\u(?<Value>[a-zA-Z0-9]{4})", RegexOptions.Compiled);
public string decodeString(string value)
{
return _regex.Replace(
value,
m => ((char)int.Parse(m.Groups["Value"].Value, NumberStyles.HexNumber)).ToString()
);
}

这是javascript的unicode编码。使用c# javascript反序列化器来转换它。

(我没有足够的声望来评论,所以我在这里写)

你最初从哪里得到这些字符的?

uXXXX是JavaScript和c#使用的编码(直到现在才知道c#这个)在字符串字面值中编码16位Unicode字符。16位- 4个十六进制字符,所以uXXXX,每个X代表一个十六进制数字。

注意,这是用来在源代码中编码字符串字面值的!它不用于编码存储在文件或内存或其他地方的字节。这是一种较旧的编码风格,因为现代源代码编辑器通常支持UTF-8或UTF-16或其他一些编码,以便能够在源代码文件中存储unicode字符,然后它们也能够显示unicode字符符号,并允许在编辑器中键入它。所以不需要输入uXXXX,而且过时了。

这就是为什么我问你最初从哪里得到字符串的原因?你写了一条评论,你是从文件中读到的?是什么生成了这个文件?

如果每个uXXXX单独作为unicode字符,这就是uXXXX的意思,在那里没有意义。00e2是带有大写字母的字符,0080和0099是控制字符,不能打印。

如果e28099被放在一起作为三个单个字节,即去掉每个字节的前00个有值的字节,因为它们以u00XX的形式存在,那么它适合作为具有十进制值2019的Unicode字符的UTF8字符表示,即"Unicode字符'右单引号' (U+2019)"然后,这就是你正在寻找的,但这似乎不正确的使用编码,生成的字符串。如果你最终得到了这些字符串,并且必须对它们求值,那么上面的注释& # c# Novice"正在工作,但它可能不是在所有情况下都有效。

您可以使用javascript脚本评估器转换在其字符串中使用uXXXX编码的字符串字面量,或使用CSharpScript.Run()来使用这些字符串字面量并分配给变量,然后查看其字节。但我后来尝试了,由于这些字节值/字符没有意义,我没有得到任何有意义的东西。我得到一个带帽的a,接下来的两个,CSharpScript拒绝解码并原样离开。因为这些字符在解码时是控制字符。

这里有三种不同的方法使用c#可用的库进行uXXXX解码。前两个使用NewtonSoft。JSON包,最后一个使用Roslyn/CSharpScript,都可以从Nuget。请注意,由于我上面描述的原因,这些都没有打印单个引号。相反,如果我将字符串更改为"u3053u3093u306Bu3061u306Fu4E16u754C!",它将在调试输出窗口上打印出这段日语文本:",谷歌翻译告诉我这是"Hello World!"的日文翻译

https://translate.google.com/?sl=ja& tl = en&文本E3 % = % E3 % 81% 93% 82% 93% E3 % af ab a1%e3 % % E3 % 81% 81% 81% 96% % E4%B8 % e7 % 95% 8 c !, op =翻译

总而言之,无论生成这些脚本的是什么,似乎都没有做标准的事情。

string test = @"Itu00e2u0080u0099s working";
// Using JSON deserialization, since uXXXX is valid encoding JavaScript string literals
// Have to add starting and ending quotes to make it a script literal definition, then deserialize as string
var d = Newtonsoft.Json.JsonConvert.DeserializeObject(""" + test + """, typeof(string));
Console.WriteLine(d);
System.Diagnostics.Debug.WriteLine(d);
// Another way of JavaScript deserialization. If you are using a stream like reading from file this maybe better:
TextReader reader = new StringReader(""" + test + """);
Newtonsoft.Json.JsonTextReader rdr = new JsonTextReader(reader);
rdr.Read();
Console.WriteLine(rdr.Value);
System.Diagnostics.Debug.WriteLine(rdr.Value);
// lastly overkill and too heavy:  Using Roslyn CSharpScript, and letting C# compiler to decode uXXXX's in string literal:
ScriptOptions opt = ScriptOptions.Default;
//opt = opt.WithFileEncoding(Encoding.Unicode);
Task<ScriptState<string>> task = Task.Run(async () => { return CSharpScript.RunAsync<string>("string str = "" + test + "".ToString();", opt); }).Result;
ScriptState<string> s = task.Result;
var ddd = s.Variables[0];
Console.WriteLine(ddd.Value);
System.Diagnostics.Debug.WriteLine(ddd.Value);

最新更新