我通过导入收到了一个未知字符编码的字符串。如何在浏览器中显示这样的字符串,以便将其复制为PHP代码?
我想用一个例子来说明这个问题。
$stringUTF8 = "The price is 15 €";
$stringWin1252 = mb_convert_encoding($stringUTF8,'CP1252');
var_dump($stringWin1252); //string(17) "The price is 15 �"
var_export($stringWin1252); // 'The price is 15 �'
与var_导出一起交付的字符串与原始字符串不匹配。所有无法识别的字符都将替换为� 象征该字符串仅在此处使用mb_convert_编码生成,用于测试目的。这里的字符编码是已知的。实际上,它来自导入,例如,带有文件内容()的导入,字符编码未知。
我所期望的具有改进的var_导出的输出如下所示:
"The price is 15 \x80"
我的解决方法是找到所有非UTF8字符,然后用十六进制显示它们。这里显示的代码过于广泛。
另一个变体是以十六进制PHP符号输出所有字符。
function strToHex2($str) {
return '\x'.rtrim(chunk_split(strtoupper(bin2hex($str)),2,'\x'),'\x');
}
echo strToHex2($stringWin1252);
输出:
\x54\x68\x65\x20\x70\x72\x69\x63\x65\x20\x69\x73\x20\x31\x35\x20\x80
这个变体非常适合纯二进制数据,但对于一般文本来说相当大且难以阅读。
换句话说,我的问题是:
如何将所有非UTF8字符从字符串更改为PHP十六进制表示“\xnn”,并保留正确的UTF8字符。
我将从问题本身开始:
如何在PHP(浏览器)中再现表示非UTF8字符串
答案很简单,只需在HTML标记或HTTP头中发送正确的编码。
但那不是你真正的问题。事实上,我不是100%确定真正的问题是什么,但我会试着遵循你写的。
我通过导入收到一个未知字符编码的字符串。
这才是我们真正需要开始的地方。如果您有一个未知字符串,那么您实际上只有二进制数据。如果您无法确定这些字节代表什么,我也不希望浏览器或其他任何人能够理解它。但是,如果您可以确定这些字节代表什么,那么再次向客户机发送正确的编码。
如何在浏览器中显示这样的字符串,以便将其复制为PHP代码?
你在这里往返,这是在问问题。唯一安全可靠的答案是Unicode,它带有一种官方支持的编码,如UTF-8、UTF-16等。
用var_export
传递的字符串与原始字符串不匹配。所有无法识别的字符都被符号替换。
作为示例输入的字符串没有以x80
的字节序列结尾。相反,您输入的€
字符在Unicode中是20AC
,并在UTF-8中表示为三个字节xE2 x82 xAC
。函数mb_convert_encoding
没有每个编码中所有逻辑字符的映射,因此对于这种特定情况,它不知道如何将“欧元符号”映射到CP1252代码页。每当字符转换失败时,将使用UnicodeFFFD
字符来代替。
该字符串仅在此处使用mb_convert_编码生成,用于测试目的。
即使这只是为了测试目的,它仍然会弄乱数据,理解前一段很重要。
这里的字符编码是已知的。实际上,它来自导入,例如带有file\u get\u contents()
,字符编码未知。
在这一点上,我们又回到了任意字节。您可以使用PHP猜测,或者如果您有已知数据的语料库,您可以构建一些启发式。
我期望的具有改进var_export的输出如下:"价格为15\x80"
var_dump
和var_export
都是为了确切地向您展示变量内部的内容,更改它们会带来巨大的BC问题。(实际上有一个RFC用于创建一个新的转储函数,但我认为它并没有达到您想要的效果。)
在PHP中,字符串只是字节数组,因此调用这些函数会将这些字节数组转储到流中,您的浏览器或控制台或其他任何程序会采用当前编码,并尝试将这些字节与当前字体匹配。如果您的字体不支持,将显示其中一个替换字符。(或者,有时设备试图猜测这些字节代表什么,这就是为什么您会看到,
或类似内容。)再说一遍,您的浏览器/控制台可以做到这一点,而PHP并没有做到这一点。
我的解决方案是查找所有非UTF8字符
那可能不是你想要的。首先,它假设字符是UTF-8,您说过这不是您可以做出的假设。第二,如果一个文件的字节序列不是有效的UTF-8,那么可能是一个坏文件。
如何将所有非UTF8字符从字符串更改为PHP十六进制表示“\xnn”,并保留正确的UTF8字符。
真正的解决方案是在应用程序中始终使用Unicode,并在存储/输出内容时强制执行编码。这也意味着,在查看这些数据时,您拥有能够显示这些代码点的字体。
当你摄取数据时,你需要先让它达到这个理智的点,这并不总是容易的。然而,一旦你是Unicode,你应该(大部分)是安全的。(对于“大部分”,我在看你表情符号!)
但你如何转化?这是最难的部分。此答案显示如何手动将CP1252转换为UTF-8。基本上,对您想要支持的每个代码点重复。
如果你不想这样做,而且你真的想得到转义序列,那么我想我应该逐字节检查字符串,然后任何超过x7F
的内容都会被转义:
$s = "The price is 15 \x80";
$buf = '';
foreach(str_split($s) as $c){
$buf .= $c >= "\x80" ? '\x' . bin2hex($c) : $c;
}
var_dump($buf);
// string(20) "The price is 15 \x80"
问题内容: 在我的雪花数据库中,一个表具有非utf8字符。我如何在它上面创建仅包含utf8字符的视图;通过排除非utf8字符的行还是替换它们?谢谢 问题答案: 应该可以使用以下测试来检查非utf: 但是那时我没有数据可以测试。 要将字符串重新编码为utf-8,可以使用JavaScript函数:
问题内容: 我在从字符串中删除非utf8字符时出现问题,这些字符无法正确显示。像这样的字符0x97 0x61 0x6C 0x6F(十六进制表示) 删除它们的最佳方法是什么?正则表达式还是其他? 问题答案: 使用正则表达式方法: 它搜索UTF-8序列,并将其捕获到组1中。它还与无法标识为UTF-8序列的一部分的单个字节匹配,但不捕获这些字节。替换是捕获到组1中的任何内容。这将有效删除所有无效字节。
问题内容: 我有一些来自json文件的文本。在本文中,我应用了UTF8编码,但是该编码器无法识别非标准字符,并且为大写字符,是否有一种方法可以净化我的字符串? 我的功能: 问题答案: 我找到了解决方案。 UTF8采用8位表ASCII表,而UTF16采用16位ASCII表,解决方案很简单,只需将函数修改为:
我正面临一个奇怪的问题。我已经把所有东西都放在php.ini文件里了。但是我不能在浏览器中显示任何错误。我google设置了. ini文件,并做了所有需要的事情。但是我仍然不能在浏览器中显示错误信息。我的PHP ini设置, 我尝试使用以下代码查看错误消息, 实际上文件示例不可用。所以它必须显示致命错误。但它显示的是空白页。 你能告诉我怎么解决这个问题吗?我不知道我错过了什么。
问题内容: 在我的servlet中,我使用下面的代码在浏览器中打开PDF文件,但是,它显示了一个下载对话框。 我做错了什么? 问题答案: 你可以尝试用
问题内容: 我们在CMS上有一个ckeditor。我们的最终用户将通过该ckeditor输入一些长文章。我们需要一种方法来防止这些文章的连字符出现换行。 无论如何,是否可以防止所有浏览器上的连字符断行? 还是ckeditor可以选择防止这种情况? 问题答案: 恐怕没有比将文本分割成“单词”(由空格分隔的非空白字符序列)并包装每个在标记内包含连字符的“单词”更可靠的方法了。因此,输入数据将变为。 您