从字符串中删除ÿþ

4

我正在尝试批量读取ID3数据。在一些音轨上出现了ÿþ。我可以删除前两个字符,但这会影响没有该字符的音轨。

以下是我目前所拥有的:

$trackartist=str_replace("\0", "", $trackartist1);

任何建议都将不胜感激,谢谢!

4
str_replace("ÿþ", "", $trackartist1); 这段代码有效吗? - Martin Tournoij
2
你能提供一个ID3数据的样本字符串吗?str_replace支持多字节字符串,@Carpetsmoker的建议似乎可行:http://codepad.org/Od59V0ki - danronmoon
1
为什么@Carpetsmoker的建议不起作用?那似乎是这里的答案。如果想进一步,可以在str_replace周围添加一个IF语句,先查看它是否以“ÿþ”开头。 - Scott
2
你能否发布一个 var_dump() 来查看你的字符串确切内容是什么? - jeroen
你应该从根本上解决这个问题。这个标记是UCS2文件BOM,在读取UCS2文件时需要对它们进行转义。https://dev59.com/GmbWa4cB1Zd3GeqPXYGN#64983143 - Zhang
显示剩余3条评论
3个回答

9

ÿþ在UTF-8中表示0xfffe;这是UTF-16中的字节顺序标记byte order mark。 您可以使用iconvmb_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);时,它会在开头切换到þÿ。 - austinh
第二个应该是mb_convert_encoding($message,'UTF-8','UTF-16LE') - n-dru

1

我曾经遇到过类似的问题,但是无法强制使用 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() 一样转换换行符):
输入图像说明


0
使用正则表达式替换:
$trackartist1 = preg_replace("/\x00?/", "", $trackartist1);

上述正则表达式寻找第一个出现的"\x00"(十六进制零),如果可能的话,将其替换为空。


@Carpetsmoker 不好意思!我以为他想要像他的代码中提到的那样去除\0字符。我没有注意到\xfffe - Cunning

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接