正确的字符编码

4

我目前正在获取一个网站的各种文本数据(当然是经过许可的)。我遇到的问题是,在这个过程中,某些字符没有正确编码。这在撇号(')方面尤为突出,导致出现了像这样的字符: 。

目前,我使用以下代码来转换从获取的数据中的各种HTML实体:

htmlentities($content, ENT_COMPAT, 'UTF-8', FALSE)

有没有更好的方法来处理这种情况?

4个回答

3

HTML实体有两个目的:

  • 转义在HTML中具有特殊含义的字符,例如角引号,以便它们可以用作字面量。
  • 显示不受您正在使用的字符集支持的字符,例如ISO-8859-1文档中的欧元符号。

它们并不是一个编码工具。

如果您想从一个字符集转换为另一个字符集,我建议您使用iconv()。但是,您必须知道源字符集和目标字符集。源字符集应在Content-Type响应头中提到,而目标字符集是您在启动网站时决定的(尽管在您的情况下,UTF-8似乎是最合理的选择)。


0

你不想立即使用htmlentities,我建议在存储数据之前的最后一步使用它。你会遇到的问题之一是人们并不总是正确地编码他们的实体。并不是每个人都使用 ™,他们只是复制商标。如果你加入一些逻辑来尝试获取他们输入的任何内容并正确编码它,你可能会更好。例如:

$patterns = array();
$patterns[0] = '/—/';
$patterns[1] = '/&nsbsp;/';
$patterns[2] = '/®/';

$replacements = array();

$replacements[2] = '&151;';
$replacements[1] = '&160;';
$replacements[0] = '&174;';

$ourhtml = preg_replace($patterns, $replacements, $html);

你可以手动查找所有的“陷阱”字符,如破折号、单引号、撇号等,并对它们进行编码,也可以使用一组标准实体(文本或数字)。

你也可以使用正则表达式来完成同样的事情,这可能是更优雅的解决方案。但我的建议是花些时间手动过滤掉不需要的内容,然后你就知道你的数据将会被准备得恰好符合你的要求。


1
那段代码的目的是什么?htmlentities将字面上的&转换为&amp;(例如,它也会对<等进行相同的操作)。你的代码似乎是将实体编码字符串从命名版本翻译成十进制版本。我不认为这是发帖者遇到的问题。此外,在这里使用preg_replace是完全多余的,str_replace就足够了。 - davidtbernal
发布的代码旨在作为示例,而不是完整的解决方案。他可以使用preg_replace来清理任何现有的实体,以确保它们被正确编码。我发布的示例将几个命名实体转换为其十进制等价物,但您也可以使用相同的方法来处理文字。 使用preg_replace的原因是它更高效,您可以创建一系列模式和替换,并使用正则表达式加速。实际上,通过足够的正则表达式,您可以在一步中完成此过滤,而不是使用str_replace 40次。 - Jeremy Morgan
str_replace()比preg_replace()更高效,因为它不需要使用正则表达式引擎。它还接受一个搜索和替换值的数组,就像你在这里使用的一样(请参见http://us.php.net/manual/en/function.substr-replace.php)。如果您实际上没有使用正则表达式(正如您的示例明确所示),则应始终使用str_repalce(),正如notJim所指出的那样。 - JamesArmes

0

根据提供的信息,建议有些困难。您能提供一小段示例文本吗?

如果没有,我会采用“散弹枪”方法(例如,建议一堆东西,希望其中一个命中)

首先,请确认您正在访问的页面是否以UTF-8编码。 mb_detect_encoding 显示什么?

一种选择(根据您的需求可能无法工作)是使用 iconvTRANSLIT 选项将字符转换为易于使用PHP处理的内容。您还可以查看使用 mb_* 函数处理多字节字符串。

您确定 htmlentities 是问题所在吗?如果内容是UTF-8,并且您的站点设置为提供ISO-8859-1,则会看到奇怪的字符。检查您的浏览器使用的编码方式,以确保其与您生成的字符的编码方式匹配。


0

只要您将最后一个参数设置为false,使用htmlentities()没有任何问题。这将确保您不会对任何内容进行两次编码(例如将&amp;转换为&amp;amp;)。


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