【问题标题】:Read a file with unicode characters读取带有 unicode 字符的文件
【发布时间】:2011-04-27 00:46:48
【问题描述】:

我有一个 asp.net c# 页面,正在尝试读取具有以下字符 ' 的文件并将其转换为 '。 (从斜撇号到撇号)。

FileInfo fileinfo = new FileInfo(FileLocation);
string content = File.ReadAllText(fileinfo.FullName);

//strip out bad characters
content = content.Replace("’", "'");

这不起作用,它会将倾斜的撇号更改为 ?标记。

【问题讨论】:

  • 你说它把倾斜的变成了“?”。这意味着您的 Replace 函数的第一个参数是正确的,但第二个参数是错误的。它可能是一个 看起来 像单引号但实际上不是单引号的 Unicode 字符。在没有 Unicode 字体的显示器中,或打印到屏幕上时,无法识别的 Unicode 字符显示为“?”。
  • 检查第二个参数是否是正确的字符。您可能不小心打开了亚洲 IME 或其他东西并输入了一个亚洲引号字符(即 Unicode),它看起来与屏幕上的简单引号完全一样。有时很难区分。
  • 是的,它与文件的读取有关。我使用了字符串内容 = File.ReadAllText(fileinfo.FullName, Encoding.Default);正确读取它。谢谢!

标签: c# asp.net unicode


【解决方案1】:

我怀疑问题不在于替换,而在于文件本身的读取。当我尝试这种 nieve 方式(使用 Word 和复制粘贴)时,我得到了与您相同的结果,但是检查 content 表明 .Net 框架认为该字符是 Unicode 字符 65533,即“怎么回事?”字符之前字符串替换。您可以通过在 Visual Studio 调试器中检查相关的 character 来自行检查,它应该在其中显示字符代码:

content[0]; // 65533 '�'

替换不起作用的原因很简单 - content 不包含您给它的字符串:

content.IndexOf("’"); // -1

至于为什么文件读取无法正常工作-您在读取文件时可能使用了错误的编码。 (如果没有指定编码,.Net 框架将尝试为您确定正确的编码,但是没有 100% 可靠的方法来做到这一点,因此它经常会出错)。您需要的确切编码取决于文件本身,但在我的情况下,使用的编码是Extended ASCII,因此要读取文件我只需要指定正确的编码:

string content = File.ReadAllText(fileinfo.FullName, Encoding.GetEncoding("iso-8859-1"));

(见this question)。

您还需要确保在替换字符串中指定正确的字符 - 在代码中使用“奇数”字符时,您可能会发现通过字符代码而不是字符串文字来指定字符更可靠(如果源文件的编码发生变化,这可能会导致问题),例如以下对我有用:

content = content.Replace("\u0092", "'");

【讨论】:

  • 相比(char)146'\u0092' 可能更具可读性,因为它匹配字符代码图表。
  • 之所以'\u0092' == (char)146是因为\u符号使用十六进制,而0x92 == 146
【解决方案2】:
// This should replace smart single quotes with a straight single quote

Regex.Replace(content, @"(\u2018|\u2019)", "'");

//However the better approach seems to be to read the page with the proper encoding and leave the quotes alone
var sreader= new StreamReader(fileInfo.Create(), Encoding.GetEncoding(1252));

【讨论】:

    【解决方案3】:

    我敢打赌,文件编码为Windows-1252。这几乎与 ISO 8859-1 相同。不同之处在于 Windows-1252 使用“可显示字符而不是 0x80 到 0x9F 范围内的控制字符”。 (这是倾斜撇号所在的位置。即 0x92)

    //Specify Windows-1252 here
    string content = File.ReadAllText(fileinfo.FullName, Encoding.GetEncoding(1252));
    //Your replace code will then work as is
    content = content.Replace("’", "'");
    

    【讨论】:

    • Encoding.GetEncoding("Windows-1252")
    【解决方案4】:

    如果你使用字符串(大写)而不是字符串,它应该能够处理你扔给它的任何 Unicode。先试试看是否可行。

    【讨论】:

    • 一个是另一个的别名,这不会改变任何东西。
    • 你是对的!然后我假设有问题的引号不是 2018/9 并且可能取决于语言环境。转换为 int 或 short 以获取 Unicode 值并将 \u+thatNumber 替换为之前发布的内容。
    猜你喜欢
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 2015-12-11
    • 2012-11-21
    • 2019-03-18
    相关资源
    最近更新 更多