【问题标题】:c# .NET isn't rendering russian charactersc# .NET 不呈现俄语字符
【发布时间】:2016-03-21 16:52:08
【问题描述】:

我正在使用正则表达式来匹配一个 unicode 字符串并将其存储在一个字符串中。例如:

注意:以下内容必须从外部文本文件中读取,否则 Visual Studio 会自动将其渲染为俄语。

"Name": "\u0412\u0438\u043d\u043d\u0438\u0446\u0430, \u0443\u043b. \u041a\u0438\u0435\u0432\u0441\u043a\u0430\u044f, 14-\u0431",

我正在使用模式:

"\"Name\":\\s*\"(?<match>[^\"]+)\""

但是,当我将匹配项存储在字符串中时,字符串会保存为:

match = "\\u0412\\u0438\\u043d\\u043d\\u0438\\u0446\\u0430, \\u0443\\u043b. \\u041a\\u0438\\u0435\\u0432\\u0441\\u043a\\u0430\\u044f, 14-\\u0431"

.NET 使用额外的“\”存储字符串

我尝试使用:

match = match.replace(@"\\", @"\") 

但 .NET 无法将 @"\\" 识别为存在,因为它正在查看“可视化器版本”。

如何在不 c# 添加额外的 '\' 的情况下存储我的 unicode?​​p>

编辑: 还有一点:

// this works!
string russianCharacters = "\u041b\u044c\u0432\u043e\u0432, \u0414\u043e\u043b\u0438\u043d\u0430, \u0432\u0443\u043b. \u0427\u043e\u0440\u043d\u043e\u0432\u043e\u043b\u0430, 18");

这会在可视化器中正确呈现为俄语字符。但是当我存储来自外部文本文件的正则表达式匹配的字符时,它被存储为一个excaped序列。

如何将我的字符串呈现为俄语字符而不是转义的 unicode 序列?

【问题讨论】:

  • 嗯,没有。 .NET 没有这样的事情。也许您会因为调试器 显示 .NET 字符串而感到困惑?尝试将字符串保存到纯文本文件,您会看到它实际 的样子(请使用Encoding.Unicode 确定)。 `\` 只存在于“可视化器”中,这就是为什么你不能替换它,反之亦然。 .NET 不是在看“可视化器”版本,而是在看。
  • 不,正在查看可视化器版本。没有双反斜杠。另外,你想通过存储这样的字符串来完成什么?
  • HTMLDecode 适用于之前使用 HTMLEncode 编码的字符串。由于您的字符串未编码,因此.net 无法解码。见msdn.microsoft.com/en-us/library/…
  • 唯一添加额外反斜杠的是调试器,仅用于显示目的。但这里似乎确实存在一个合理的问题,只是初步分析错误。你的数据来自哪里?它有 Unicode 字符或转义序列吗?
  • @WiktorStribiżew 谢谢!!做到了!如果你想发布一个正式的答案,我可以给你赏金。谢谢!

标签: c# .net regex


【解决方案1】:

您似乎从一个实际包含文字 Unicode 点的文本文件中读取了字符串,而不是实际的 Unicode 符号。也就是说,您的 C# 变量如下所示:

var match = "\\u0412\\u0438\\u043d\\u043d\\u0438\\u0446\\u0430, \\u0443\\u043b. \\u041a\\u0438\\u0435\\u0432\\u0441\\u043a\\u0430\\u044f, 14-\\u0431"

var match = @"\u0412\u0438\u043d\u043d\u0438\u0446\u0430, \u0443\u043b. \u041a\u0438\u0435\u0432\u0441\u043a\u0430\u044f, 14-\u0431"

在这种情况下,要获取实际的 Unicode 字符串,您需要使用Regex.Unescape

转换输入字符串中的任何转义字符。

C# demo:

var s = "\\u0412\\u0438\\u043d\\u043d\\u0438\\u0446\\u0430, \\u0443\\u043b. \\u041a\\u0438\\u0435\\u0432\\u0441\\u043a\\u0430\\u044f, 14-\\u0431";
Console.WriteLine(s); 
// \u0412\u0438\u043d\u043d\u0438\u0446\u0430, \u0443\u043b. \u041a\u0438\u0435\u0432\u0441\u043a\u0430\u044f, 14-\u0431
Console.WriteLine(Regex.Unescape(s));
// Винница, ул. Киевская, 14-б

【讨论】:

  • 绝妙的解决方案!
【解决方案2】:

额外的“\”只是一个转义字符。我猜您正在调试器窗口中查看该值,在这种情况下,它会显示额外的“\”,但基础值不会有额外的“\”。尝试使用实际值,您会看到这一点。

此代码按预期工作:

var myString = "\"Name\": \"\u0412\u0438\u043d\u043d\u0438\u0446\u0430, \u0443\u043b.\u041a\u0438\u0435\u0432\u0441\u043a\u0430\u044f, 14 - \u0431\",";
var pattern = "\"Name\":\\s*\"(?<match>[^\"]+)\"";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection matches = rgx.Matches(myString);

if (matches.Count > 0)
{
    foreach (Match match in matches)
    {
        var ma = System.Web.HttpUtility.HtmlDecode(match.ToString());
    }
}

【讨论】:

  • 如何正确地将 unicode 渲染为俄语字符?可视化工具显示 \u0412\u0438\u043d\u043d\u0438\u0446\u0430, \u0443\u043b。 \u041a\u0438\u0435\u0432\u0441\u043a\u0430\u044f, 14-\u0431 这是正确的,但我希望字符串实际呈现为俄语字符
  • 仍然不适合我。在您的示例中, myString 会自动呈现为俄语字符。但是,如果您将正则表达式与外部文本文件匹配,它将保存为转义的 unicode 序列,而不是实际的俄罗斯字符
猜你喜欢
  • 1970-01-01
  • 2012-02-16
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多