1

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

... of var¬ious Federal ...

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

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

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

... of var�ious Federal ...

为什么会发生这种情况,我能做些什么来解决它?

4

2 回答 2

2

字符集和编码简介

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

这样的系统称为字符编码。由于编码必须由计算机实现,因此它们需要明确定义,因此每种编码只能处理一组预定义的字符,这毫不奇怪称为字符集

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

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

回到你的问题

当您将文本文件保存到磁盘时,记事本使用了某种编码(这是一种多字节编码,但我们暂时假设我们不知道)。文本中的字符¬以字节的形式给出了一些特定的表示。

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

默认情况下preg_replace,就像 PHP 中的所有通用字符串函数一样,以二进制模式运行。这意味着它以字节为单位工作。这与您的源代码编辑器形成对比,后者具有编码意识并以字符的形式显示源代码。结果,当您替换您认为是字符¬NOT SIGN)时,preg_replace实际上替换了一系列字节,其确切形式取决于您的 PHP 源代码的编码。

这就是问题所在:如果文本文件的编码与您的源代码不匹配,那么所有关于文本可能实际发生的事情的赌注都将落空。

鉴于您显示的结果,您的情况很可能是这样的:

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

如何修复它

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

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

    preg_replace("/\xc2\xa2/", '', $string)
    

    并且只要文本文件编码保持 UTF-8,无论您的 PHP 源代码是什么编码,它都可以工作。

于 2013-09-05T22:04:43.517 回答
0

尝试

$string = mb_convert_encoding($string, "UTF-8");
echo $string;
于 2013-09-05T22:03:05.040 回答