我需要自动确定字符编码的字符串从电子邮件内容和标题。在大多数情况下,这不是一个问题,但偶尔有一个电子邮件的内容和/或标题有一个古怪的字符,如一个恩达什。现在,我收到了一个答案,从技术上讲,如果我在一个特定的邮件头上静态地测试它,那么这个答案似乎是有效的,但是,这显然忽略了一个事实,即导入电子邮件必须是一个完全自动化的过程,在这种情况下,我完全无法自动确定字符串的字符编码。
我从一些基本知识开始,比如检测常见的故障字符,这些字符似乎保证了字符编码问题的发生。然而,strpos('en dash: –', '–')在有意/手动测试时运行良好,尽管它在直接添加到自动化过程时会彻底失败。我将猜测,问题是字符串参数具有UTF-8编码,而自动化过程正在测试一个尚未UTF-8的字符串,因此内部相同的字符没有使用相同的代码子集(通过字符编码)。
因此,我的第二次尝试是编码的第二个参数可以是一个数组。
$encodings = array('UTF-8','UCS-4','UCS-4BE','UCS-4LE','UCS-2','UCS-2BE','UCS-2LE','UTF-32','UTF-32BE','UTF-32LE','UTF-16','UTF-16BE','UTF-16LE','UTF-7','UTF7-IMAP','ASCII','EUC-JP','SJIS','eucJP-win','SJIS-win','ISO-2022-JP','ISO-2022-JP-MS','CP932','CP51932','SJIS-mac','SJIS-Mobile#DOCOMO','SJIS-Mobile#KDDI','SJIS-Mobile#SOFTBANK','UTF-8-Mobile#DOCOMO','UTF-8-Mobile#KDDI-A','UTF-8-Mobile#KDDI-B','UTF-8-Mobile#SOFTBANK','ISO-2022-JP-MOBILE#KDDI','JIS','JIS-ms','CP50220','CP50220raw','CP50221','CP50222','ISO-8859-1','ISO-8859-2','ISO-8859-3','ISO-8859-4','ISO-8859-5','ISO-8859-6','ISO-8859-7','ISO-8859-8','ISO-8859-9','ISO-8859-10','ISO-8859-13','ISO-8859-14','ISO-8859-15','ISO-8859-16','byte2be','byte2le','byte4be','byte4le','BASE64','HTML-ENTITIES','7bit','8bit','EUC-CN','CP936','GB18030','HZ','EUC-TW','CP950','BIG-5','EUC-KR','UHC','ISO-2022-KR','Windows-1251','Windows-1252','CP866','KOI8-R','KOI8-U','ArmSCII-8');
$encoding = mb_detect_encoding($s, $encodings, true);
$compare = mb_convert_encoding($s, 'UTF-8', $encoding);
foreach ($encodings as $k1)
{
if (mb_convert_encoding($s, 'UTF-8', $k1) === $s) {$encoding = $k1; break;}
}不幸的是,基于我认为同样的根本问题,这似乎导致了同样的失败。
因此,我的第三个想法,我正在寻找一些更有经验的验证。我可以将字符串转换成二进制形式(1和0,而不是二进制数据)。然后,我可以尝试转换字符串,然后将第二个字符串转换为二进制,以比较这两个二进制版本;如果它们===匹配,那么我可能已经确定了正确的字符编码?
现在,我可以很容易地从一个不相关的线程尝试这个有了这个答案,但是我不确定这是否是一个有效的想法。这一切都是为了回答我的问题:
如何确定字符串的实际字符编码,以便在不损坏数据的情况下将其转换为具有完全自动化验证的UTF-8?
通过验证,我说的是一些东西,比如比较二进制数据,但我不确定这是否有效。我知道我非常讨厌破折号。
发布于 2021-11-25 11:53:44
答案不会改变:这是不可能的。您必须依赖于文本上使用的外部信息进行编码。
猜测编码可能会出现可怕的错误:
还有:1和0是二进制的。PHP字符串只是字节数组。,所以它们一开始是二进制的。如何解释它们取决于您:如果您的代码是$text= "グリーン";,那么就取决于您的PHP文本文件的编码方式以及如何设置PHP默认值。没有“内部.字符”,只有字节。这也是为什么存在在字节(即strlen())和特定文本编码(即mb_strlen())上操作的函数。
如果你讨厌单个字符,那么它们可以很容易地用作文本中的字符。-与-、-和-相比,有它自己的有效意义;不要用个人观点来代替它,因为这可能会破坏上下文的意义。这就像忽略了这样一个事实:一个和Α以及一个都是不同的字符。您可能需要查找_homo_glyphs和_syno_glyphs之间的区别-后者是您当前的透视图。
您可能会问:“PHP在哪种编码中解释脚本?”幸运的是,对于大多数编码来说,ASCII是最常见的分母,因此将文件的第一个字节解释为搜索<?php (所有这些都是ASCII字符,所以对于PHP代码本身来说,它实际上是UTF-8还是ISO-8859-1或< code >E 142Shift-JISE 243)只有在文档被编码时才会失败,即E 144UTF-16e 245/code>-在这种情况下,您必须将您的PHP默认值设置为该编码。这再次证明:文本编码必须在文本之外被告知。
https://stackoverflow.com/questions/70037066
复制相似问题