我正在尝试批量读取ID3数据。在一些音轨上出现了ÿþ。我可以删除前两个字符,但这会影响没有该字符的音轨。
以下是我目前所拥有的:
$trackartist=str_replace("\0", "", $trackartist1);
任何建议都将不胜感激,谢谢!
ÿþ
在UTF-8中表示0xfffe;这是UTF-16中的字节顺序标记byte order mark。
您可以使用iconv
或mb_convert_encoding()
将字符串转换为UTF-8:
$trackartist1 = iconv('UTF-16LE', 'UTF-8', $trackartist1);
# Same as above, but different extension
$trackartist1 = mb_convert_encoding($trackartist1, 'UTF-16LE', 'UTF-8');
# str_replace() should now work
$trackartist1 = str_replace('ÿþ', '', $trackartist1);
假定$trackartist1
始终为UTF-16LE格式;请查看您的ID3标签库文档以获取标签的编码方式,因为对于不同的文件可能会有所不同。通常您希望将所有内容转换为UTF-8格式,因为这是PHP默认使用的格式。
$trackartist1 = iconv('UTF-8', 'UTF-16', $trackartist1);
和str_replace('ÿþ', '', $trackartist1);
时,它会在开头切换到þÿ。 - austinhmb_convert_encoding($message,'UTF-8','UTF-16LE')
。 - n-dru我曾经遇到过类似的问题,但是无法强制使用 UTF-16LE
作为输入字符集,因为输入字符集可能会发生变化。最终,我通过以下方式检测 UTF-8
:
if (!preg_match('~~u', $html)) {
如果失败了,我会通过BOM 获得正确的编码:
function detect_bom_encoding($str) {
if ($str[0] == chr(0xEF) && $str[1] == chr(0xBB) && $str[2] == chr(0xBF)) {
return 'UTF-8';
}
else if ($str[0] == chr(0x00) && $str[1] == chr(0x00) && $str[2] == chr(0xFE) && $str[3] == chr(0xFF)) {
return 'UTF-32BE';
}
else if ($str[0] == chr(0xFF) && $str[1] == chr(0xFE)) {
if ($str[2] == chr(0x00) && $str[3] == chr(0x00)) {
return 'UTF-32LE';
}
return 'UTF-16LE';
}
else if ($str[0] == chr(0xFE) && $str[1] == chr(0xFF)) {
return 'UTF-16BE';
}
}
现在我能够使用iconv()
,就像你在@carpetsmoker答案中看到的那样:
iconv(detect_bom_encoding($html), 'UTF-8', $html);
我没有使用 mb_convert_encoding()
,因为它不会删除BOM(也不像 iconv()
一样转换换行符):
$trackartist1 = preg_replace("/\x00?/", "", $trackartist1);
上述正则表达式寻找第一个出现的"\x00"(十六进制零),如果可能的话,将其替换为空。
\0
字符。我没有注意到\xfffe
。 - Cunning
str_replace("ÿþ", "", $trackartist1);
这段代码有效吗? - Martin Tournoijvar_dump()
来查看你的字符串确切内容是什么? - jeroen