为什么我不能摆脱这个?

时间:2010-08-30 00:04:42

标签: php encoding

每一行都是一个字符串

 4 
 minutes 
 12
 minutes
 16
 minutes

我能够使用Â成功删除str_replace,但不能使用HTML实体。我发现了这个问题:How to remove html special chars?

但preg_replace没有完成这项工作。如何删除HTML实体和A?

修改 我想我应该早些说过:我正在使用DOMDocument::loadHTML()DOMXpath修改 由于这似乎是一个编码问题,我应该说这实际上是所有单独的字符串。

2 个答案:

答案 0 :(得分:18)

好吧 - 我想我现在已经掌握了这个 - 我想扩展一些人们所遇到的编码错误:

这似乎是Mojibake的一个高级案例,但这是我认为正在发生的事情。 MikeAinOz最初怀疑这是UTF-8数据可能是真的。如果我们采用以下UTF-8数据:

4 minutes

现在,删除HTML实体,并将其替换为实际对应的字符:U + 00A0。 (这是一个不间断的空间,所以我不能完全“显示”你。你得到字符串:“4分钟”。将其编码为UTF-8,你得到以下字节序列:

characters:  4  [nbsp]   m   i   n ...
bytes     : 34  C2  A0  6D  69  6E ...

(我使用上面的[nbsp]来表示一个字面不间断的空格(字符,而不是HTML实体 ,但是代表的字符。它只是白色空间,因此很难。)请注意,[nbsp] / U + 00A0(非中断空格)需要2个字节才能以UTF-8进行编码。

现在,为了从字节流回到可读文本,我们应该使用UTF-8解码,因为这是我们编码的。让我们使用ISO-8859-1(“latin1”) - 如果你使用错误的,这几乎总是如此。

bytes     : 34  C2      A0  6D  69  6E ...
characters:  4   Â  [nbsp]   m   i   n ...

将原始的非破坏空间切换为HTML实体表示,然后就可以获得所需内容。

所以,你的PHP内容是用错误的字符集解释你的文本,你需要告诉它,否则你在错误的字符集中以某种方式输出结果。更多代码在这里很有用 - 你在哪里获得你传递给这个loadHTML的数据,你将如何获得你所看到的输出?


一些背景:“字符编码”只是从一系列字符到一系列字节的一种方式。什么字节代表“é”? UTF-8表示C3 A9,而ISO-8859-1表示E9。要从一系列字节中恢复原始文本,我们必须知道我们用它编码的内容。如果我们将C3 A9解码为UTF-8数据,我们会收回“é”,如果我们(错误地)将其解码为ISO-8859-1,我们会得到“é”。垃圾。在伪代码中:

utf8-decode ( utf8-encode ( text-data ) )           // OK
iso8859_1-decode ( iso8859_1-encode ( text-data ) ) // OK
iso8859_1-decode ( utf8-encode ( text-data ) )      // Fails
utf8-decode ( iso8859_1-encode ( text-data ) )      // Fails

这不是PHP代码,而不是你的修复......这只是问题的症结所在。在某个地方,大规模,正在发生,事情很困惑。

答案 1 :(得分:0)

这看起来像编码错误 - 您的文档使用UTF-8编码,但是呈现为ASCII。解决编码不匹配问题将解决您的问题。在使用utf8_decode()

之前,您可以尝试在源上使用DOMdocument::loadHTML()

Here's an alternative solution from the DOMdocument::loadHTML() documentation page