清理输入文本:未正确编码的字符

时间:2013-09-05 21:29:51

标签: php text encoding

当我将文字从word文档复制并粘贴到记事本时,我会得到这些奇怪的字符(可能是由于编码问题),如此

... of var¬ious Federal ...

“¬”是奇怪的编码符号。当我在PHP中读取文本文件时,我想删除所有这些奇怪编码的符号。我尝试用空字符串替换“¬”

return preg_replace('/¬/', '', $string); 

但是当我将文本返回到HTML网页时,只会导致另一个奇怪的字符代替单词

... of var�ious Federal ...

为什么会发生这种情况,我该怎么做才能解决这个问题?

2 个答案:

答案 0 :(得分:2)

简要介绍字符集和编码

当文档显示在屏幕上时,人们将它们解析为字符序列(在计算机文本处理的上下文中也称为字形)。但是,当文档存储在磁盘上时,它们将被写为 bytes 的序列,就像所有其他类型的文件一样。因此,必须有一个系统来处理从字符到字节的转换,反之亦然。

这样的系统称为字符编码。由于编码必须由计算机实现,因此需要对其进行定义,因此每个编码只能处理一组预定义的字符,这不足为奇地称为字符集

有些编码总是用单个字节表示每个字符;这些被称为单字节编码。其他编码对每个字符使用多个字节,并且对于所有可能的字符不一定使用相同的数字;这些被称为多字节编码

回顾一下:文本文档在逻辑上包含字符,这些字符是从某些预定义的字符集中提取的,但是计算机以字节为单位工作,因此我们组成字符将字符转换为字节的编码,反之亦然。有些编码称为多字节,因为它们使用多个字节来表示单个字符。

回到你的问题

当您将文本文件保存到磁盘时,Notepad使用了一些编码来执行此操作(它是一种多字节编码,但我们假装现在还不知道)。文本中的字符¬以字节的形式给出了一些特定的表示。

当您将PHP文件保存到磁盘时,源代码编辑器使用了一些编码来执行此操作。字符串文字'/¬/'中的字符¬以字节的形式给出了一些特定的表示。

默认情况下,preg_replace与PHP中的所有通用字符串函数一样,以二进制模式运行。这意味着它适用于 bytes 。这与源代码编辑器形成对比,源代码编辑器具有编码感知功能,并以字符的形式显示源代码。因此,当您替换您认为的字符¬NOT SIGN)时,preg_replace实际上会替换一系列字节,其中depends on the encoding的确切形式为你的PHP源代码。

其中存在的问题是:如果文本文件和源代码的编码不匹配,则所有投注都将关闭文本实际可能发生的事情。

根据您显示的结果,您的案例中发生的事情很可能就是这样:

  1. 文本文件以某种多字节编码保存。
  2. PHP源代码以单字节编码保存。
  3. PHP源代码中¬的单字节表示形式是文本中¬的多字节表示的一部分,因此消除了这些字节中的一个
  4. 其余的字节不符合编码规则,因此在替换后显示文本的程序显示一个问号,说“这里有东西,但它不是我认识的字符”。< / LI>

    如何解决

    几种可能性都与上述一致,但它们都有一个共同的属性:你必须知道文本文件的编码(你可以用记事本轻松做到这一点:“另存为“并查看对话框的底部)。然后你可以:

    • 使用相同的编码保存您的文本文件和PHP源代码,一切都会正常工作。到目前为止,这是最简单的。
    • 在PHP源代码中注入代表文本文件编码中目标字符的字节。例如,假设文本文件保存为UTF-8。此编码用字节序列0xC2 0xA2表示有问题的字符,因此您可以通过将代码写为

      来替换此字节序列
      preg_replace("/\xc2\xa2/", '', $string)
      

      只要文本文件编码保持为UTF-8,无论您的PHP源代码是什么,这都将有效。

答案 1 :(得分:0)

$string = mb_convert_encoding($string, "UTF-8");
echo $string;