页面上显示的是“’”而不是“'”。

191

我的页面上显示的是’,而不是'

我已经在<head>标签和HTTP头中都将Content-Type设置为UTF-8

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

enter image description here

此外,我的浏览器设置为 Unicode (UTF-8)

enter image description here

那么问题是什么,我该怎么解决呢?


1
请参考以下链接中的“乱码”:https://dev59.com/WFoT5IYBdhLWcg3wnQn9 - Rick James
12个回答

282

那么问题是什么呢,

问题出在一个右单引号 - U+2019)字符被解码为CP-1252而不是UTF-8。如果您查看FileFormat.Info上此字符的编码表,则会发现该字符在UTF-8中由字节0xE20x800x99组成。 enter image description here

如果您查看维基百科上的CP-1252代码页布局,则会发现十六进制字节E28099分别代表单个字符â在此输入图片描述


“我该如何修复它?” 使用UTF-8来读取、写入、存储和显示字符,而不是CP-1252。

I have the Content-Type set to UTF-8 in both my <head> tag and my HTTP headers:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

这只是指示客户端使用哪种编码来解释和显示字符。这并不指示您自己的程序使用哪种编码来读取、写入、存储和显示字符。确切的答案取决于服务器端平台/数据库/编程语言的使用情况。请注意,设置在HTTP响应头中的优先于HTML元标记。当页面通过http(s):// URL而不是通过file:// URL从本地磁盘文件系统打开时,才会使用HTML元标记。


此外,我的浏览器设置为Unicode (UTF-8):这只是强制客户端使用哪种编码来解释和显示字符。但实际问题是,您已经向客户端发送了编码为UTF-8的确切字符’,而不是字符。客户端基本上使用UTF-8编码正确显示’。如果客户端被错误地指示使用例如ISO-8859-1来显示它们,那么您可能会看到ââ¬â¢
我正在使用带有数据库的ASP.NET 2.0。
这很可能是你的问题所在。你需要用一个独立的数据库工具验证数据的样子。
如果 " ' " 字符正确存在,那么你很可能没有从程序中正确连接到数据库。你基本上需要重新配置数据库连接器以使用UTF-8。如何做这取决于使用的数据库。
或者如果你的数据库已经包含 "’",那么它就是你的数据库出了问题。很可能表没有配置为使用UTF-8。相反,它们使用数据库的默认编码,这取决于配置。如果这是你的问题,通常仅改变表使用UTF-8就足够了。如果你的数据库不支持,你需要重新创建表。在创建表时设置表的编码是一个好习惯。
你很可能正在使用SQL Server,但是这里有一些MySQL代码(从this article复制):
CREATE DATABASE db_name CHARACTER SET utf8;
CREATE TABLE tbl_name (...) CHARACTER SET utf8;

如果您的表格已经是UTF-8格式, 那么您需要退后一步。谁或什么把数据放在那里,那就是问题所在。一个例子就是HTML表单提交的值被错误编码/解码。

以下是一些更多关于这个问题的学习链接:


2
如果您在某个地方保存了像这样的破损内容,例如在MySQL数据库中,https://dev59.com/nGox5IYBdhLWcg3wIQ_3#9407998提供了您需要将字符转换为UTF-8的技巧。 - Steve
12
TL;DR:使用UTF-8来读取、编写、存储和显示字符。 - c0degeas
1
请注意,iso-8859-1和Windows-1252表重叠,因此一些“奇怪的字符组合”对两者都很常见(例如,“é”表示“é”)。 - Skippy le Grand Gourou
@c0degeas 这应该是被接受的答案。 - El Ectric
我们的第三方通过请求发送给我们的网络服务(电子邮件内容)带有声称信息为UTF-8的标头,但我发现出现了这样的字符。有没有解决这个问题的办法? - Tristen Woodruff
显示剩余2条评论

63

确保浏览器和编辑器使用UTF-8编码而不是ISO-8859-1/Windows-1252。

或使用&rsquo;


83
不,问题没有解决。你的应用程序中仍存在字符编码不一致的问题。将来遇到其他非CP1252字符时,你还会再次遇到同样的问题。而且这类字符还有很多... - BalusC
13
你将继续遇到的字符示例:http://www.i18nqa.com/debug/utf8-debug.html - Zoot
为了给我之前的评论提供一些背景,OP实际上发表了以下评论:"或者使用’" . 问题解决。但显然,OP几年后意识到他当时的错误非常尴尬,所以删除了他的评论。 - undefined

25

(Unicode代码点为U+2019 RIGHT SINGLE QUOTATION MARK)在UTF-8中的字节编码为:

0xE2 0x80 0x99

’(Unicode代码点为U+00E2 U+20AC U+2122)在UTF-8中的字节编码为:

0xC3 0xA2 0xE2 0x82 0xAC 0xE2 0x84 0xA2

这些是浏览器实际接收到的字节,以便在使用UTF-8处理时生成’

这意味着您的源数据在发送到浏览器之前要经过两次字符集转换:

  1. 源码中的字符(U+2019)首先被编码为UTF-8字节:

    0xE2 0x80 0x99

  2. 这些个别字节然后被一个Windows-125X字符集(1252、1254、1256和1258都将0xE2 0x80 0x99映射到U+00E2 U+20AC U+2122错误解释并解码为Unicode代码点U+00E2 U+20AC U+2122,然后将这些代码点编码为UTF-8字节:

    0xE2 -> U+00E2 -> 0xC3 0xA2
    0x80 -> U+20AC -> 0xE2 0x82 0xAC
    你需要找到第二步中进行额外转换的地方并将其删除。 0x99 -> U+2122 -> 0xE2 0x84 0xA2


18

我有一些文档,其中显示为…,而ê显示为ê。这是它如何出现的(Python代码):

# Adam edits original file using windows-1252
windows = '\x85\xea' 
# that is HORIZONTAL ELLIPSIS, LATIN SMALL LETTER E WITH CIRCUMFLEX

# Beth reads it correctly as windows-1252 and writes it as utf-8
utf8 = windows.decode("windows-1252").encode("utf-8")
print(utf8)

# Charlie reads it *incorrectly* as windows-1252 writes a twingled utf-8 version
twingled = utf8.decode("windows-1252").encode("utf-8")
print(twingled)

# detwingle by reading as utf-8 and writing as windows-1252 (it's really utf-8)
detwingled = twingled.decode("utf-8").encode("windows-1252")

assert utf8==detwingled

为了解决这个问题,我使用了像这样的Python代码:

with open("dirty.html","rb") as f:
    dt = f.read()
ct = dt.decode("utf8").encode("windows-1252")
with open("clean.html","wb") as g:
    g.write(ct)

因为有人把twingled版本插入到一个正确的UTF-8文档中,所以我只需要提取twingled部分,解twingle并重新插入。我使用了BeautifulSoup来完成这个过程。

与其说是web服务器配置错误,不如说你在内容创建时可能出现了Charlie(指字符编码错误)。你也可以通过选择windows-1252编码来强制让你的Web浏览器对页面进行twingle。但是,你的Web浏览器无法解twingle Charlie保存的文档。

注意:同样的问题也可能会发生在任何其他单字节代码页(例如Latin-1)中,而不仅仅是在windows-1252中。


18

当一个字符串被转换两次从Windows-1252到UTF-8时,有时会出现这种情况。

我们在一个Zend/PHP/MySQL应用程序中遇到了这个问题,这些字符似乎是因为MySQL连接没有指定正确的字符集而出现在数据库中的。我们不得不:

  1. 确保Zend和PHP在与数据库通信时使用UTF-8(默认情况下不是

  2. 使用几个像这样的SQL查询修复损坏的字符...

    UPDATE MyTable SET 
    MyField1 = CONVERT(CAST(CONVERT(MyField1 USING latin1) AS BINARY) USING utf8),
    MyField2 = CONVERT(CAST(CONVERT(MyField2 USING latin1) AS BINARY) USING utf8);
    

    根据需要对尽可能多的表格/列执行此操作。

如果有必要,您还可以在PHP中修复其中一些字符串。请注意,由于字符已经被编码两次,因此实际上我们需要将其从UTF-8反向转换Windows-1252,这最初让我感到困惑。

mb_convert_encoding('’', 'Windows-1252', 'UTF-8');    // returns ’

太棒了!我在整个互联网上都试过了,只有这个有效 :) 谢谢兄弟... - Shurvir Mori
非常感谢!我差点因为这个编码问题而发疯! - Philippe

11

您的字符编码不匹配;您的字符串使用一种编码(UTF-8),而解释此页面的任何内容都使用另一种编码(比如ASCII)。

请始终在http标头中指定编码,并确保与您的框架定义的编码相匹配。

示例HTTP标头:

Content-Type    text/html; charset=utf-8

在ASP.NET中设置编码方式

<configuration>
  <system.web>
    <globalization
      fileEncoding="utf-8"
      requestEncoding="utf-8"
      responseEncoding="utf-8"
      culture="en-US"
      uiCulture="de-DE"
    />
  </system.web>
</configuration>

设置jsp中的编码


8
如果您的内容类型已经是UTF8,则很可能数据已经以错误的编码到达。如果您从数据库获取数据,请确保数据库连接使用UTF-8。
如果这是来自文件的数据,请确保文件正确地编码为UTF-8。您通常可以在所选编辑器的“保存为…”对话框中设置此选项。
如果在查看源文件时数据已经损坏,那么很有可能它曾经是一个UTF-8文件,但在某个地方以错误的编码保存了。

6

如果在WordPress网站上出现此错误,您需要更改wp-config数据库字符集:

define('DB_CHARSET', 'utf8mb4_unicode_ci');

替代方案:

define('DB_CHARSET', 'utf8mb4');

1
感谢您,救命恩人先生。 - Agent K

4
如果其他答案没有帮助到你,你可能需要检查一下你的数据库是否实际存储了乱码字符。我在使用utf-8查看文本时仍然看到了乱码,后来发现由于数据库升级,文本已经永久性地“乱码”了。
在这种情况下,一个选择是使用Python的ftfy包(或JavaScript版本here)来“修复”文本。

当我写了一个质量不高的ftfy库的时候,5年前我真的需要这个答案。 - Michael

1
在DBeaver(或其他编辑器)中,您正在使用的脚本文件可以提示保存为UTF8,这将更改字符:– 为:
–

或者

–

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接