Php 检测和删除(或修复)由错误编码转换导致的错误字符的任何方法

Php 检测和删除(或修复)由错误编码转换导致的错误字符的任何方法,php,character-encoding,Php,Character Encoding,我正在写一个解析器。我已经正确地处理了输出UTF-8的所有编码转换,但有时源材料不正确。例如☐或–tm-错误编码转换的结果 我知道这是一个长期的尝试,但有人知道一个由错误的字符转换导致的常见字符串列表,或者任何我不必构建自己的列表的东西 是的,我知道我很懒,但我读过一些使我成为一名优秀程序员的书;dr:见最后两段 我讨厌/喜欢编码问题 我们正在寻找一个变异的基因。该字符的字节序列为0xE2 0x80 0x99。在Windows-1252中,对应于+帽子、欧元和商标符号(™). 我们看到的“t

我正在写一个解析器。我已经正确地处理了输出UTF-8的所有编码转换,但有时源材料不正确。例如
–tm
-错误编码转换的结果

我知道这是一个长期的尝试,但有人知道一个由错误的字符转换导致的常见字符串列表,或者任何我不必构建自己的列表的东西


是的,我知道我很懒,但我读过一些使我成为一名优秀程序员的书;dr:见最后两段


我讨厌/喜欢编码问题

我们正在寻找一个变异的基因。该字符的字节序列为
0xE2 0x80 0x99
。在Windows-1252中,对应于+帽子、欧元和商标符号(™). 我们看到的“tm”是将该商标符号进一步音译为ASCII t和ASCII m,
0x74 0x6D
,使我们的最终损坏字节序列
0xE2 0x80 0x74 0x6D

很可能a+hat-euro-t-m的实际表示形式已经在UTF-8中。也就是说,a+hat是一个UTF-8序列,euro符号也是一个UTF-8序列,因为有人从已经不正确编码的Windows-1252文档复制并粘贴到UTF-8文档中。你会发现它的字节比四个字节多得多从原来的腐败

解决此问题的一种方法是首先将这些字符的UTF-8编码转换回Windows-1252,然后在将其写回时将该Windows-1252字符串视为UTF-8

为此,您可以与
//translatit
标志一起使用:

$less_bad = iconv('UTF-8', 'Windows-1252//TRANSLIT', $bad);
这会告诉iconv尝试将Windows-1252中无法表示的任何字符转换为类似的字符。此转换不完美,将销毁Windows-1252中无法表示的任何合法UTF-8字符

一旦你有了Windows-1252字符串,就把它保存起来,作为UTF-8提供。如果一切顺利,损坏应该消失了,你不应该有任何问题

是的,对

在这种特定情况下,正确序列的最后一个字节,
0x99
,已被错误的复制/粘贴分为两个字节。您无法通过字符集编码跳转将其取回

虽然跳转可能适用于某些文档,但您肯定会发现许多重新编码更糟糕的东西。您最好的选择是执行字节级搜索和替换操作,查找编码错误的序列,并用普通ASCII或正确的UTF-8编码的替代品替换它们。编码错误的方式很多。例如,如果损坏源在ISO-8859系列中,则最终损坏的序列可能会不同,或者可能是最终损坏的序列™ 可能不会在某些地方咀嚼
t
m

字节级搜索和替换保证只会影响错误的重新编码序列,并且不会留下在劣质字符集中无法表示的单个编码UTF-8字符上咀嚼的风险。它更安全、更快



编辑:我完全没有意识到你已经计划这么做了。;)不幸的是,我从来没有见过这么方便的列表。也许你应该出版和宣传你的作品,让别人受益
yourcharacterencodingsucks.com
可用

当人们说懒惰使你成为一名优秀的程序员时,他们指的是那种懒惰,你知道自己的选择,你选择了最简单的一个,这并不愚蠢。看起来这就是你正在做的,所以这很好:)为什么你不能使用mb_*或其他编码函数?编码和错误是很久以前由不是我的人创建的。我正在把一堆旧的html页面转换成utf-8,但是有很多已经在以前的编码转换中有了根深蒂固的错误。如果我真的这样做了,我一定会发布这个列表。至少把它贴在这里,不管怎样,还是要问问题。