搜索并替换特殊字符PHP

时间:2010-10-08 23:44:32

标签: php

我正在尝试搜索和替换我从csv文件解析的字符串中的特殊字符。当我用vim打开文本文件时,它向我显示字符是< 95> 。我不能为我的生活弄清楚这是用什么字符来使用preg_replace。任何帮助,将不胜感激。

谢谢,

Chris Edwards

2 个答案:

答案 0 :(得分:4)

0x95可能应该代表{+ 3}}中编码的字符U + 2022 Bullet()。您可以使用以下命令在字节串中删除它:

$line= str_replace("\x95", '', $line);

或者您可以使用iconv将数据的字符集从cp1252转换为utf8(或您想要的任何其他编码),如果您有一个CSV解析器,可以可靠地读取非ASCII字符。否则,您可能希望删除所有非ASCII字符,例如:

$line= preg_replace("/[\x80-\xFF]/", '', $line);

如果您的CSV解析器为fgetcsv(),则表示您遇到了问题。从理论上讲,您应该能够将其作为字符串的预处理步骤,然后再将其传递给str_getcsv()(PHP 5.3)。不幸的是,这也意味着您必须自己逐行读取文件并将其拆分,这一点并非易事,因为引用的CSV值可能包含换行符。当你编写代码以正确处理时,你几乎已经编写了一个CSV解析器。因此,您实际需要做的是将文件读入字符串,进行预处理更改,将其写回临时文件,然后fgetcsv()读取

另一种方法是单独对fgetcsv()返回的每个字符串进行后处理。但这也是不可预测的,因为PHP通过使用系统默认编码对其进行解码来破坏输入,而不是仅仅给出该死的字节。 Windows外部的默认编码通常是UTF-8,它本身不会读取0x95字节,因为它是一个无效的字节序列。虽然您可以尝试使用setlocale()更改系统默认编码来解决这个问题, 是非常糟糕的做法,这与您运行的任何其他应用程序无法很好地协作取决于系统区域设置。

总之,PHP的内置CSV解析功能非常糟糕。

答案 1 :(得分:1)

根据Bobince的建议,以下内容对我有用:

analyse_file() - > http://www.php.net/manual/en/function.fgetcsv.php#101238

function file_get_contents_utf8($fn) {
    $content = file_get_contents($fn);
    return mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));
}


if( !($_FILES['file']['error'] == 4) ) {
    foreach($_FILES as $file) {
        $n = $file['name'];
        $s = $file['size'];
        $filename = $file['tmp_name'];
        ini_set('auto_detect_line_endings',TRUE); // in case Mac csv
        // dealing with fgetcsv() special chars
        // read the file into a string, do your pre-processing changes
        // write it back out to a temporary file, and have fgetcsv() read that.
        $file = file_get_contents_utf8($filename);
        $tempFile = tempnam(sys_get_temp_dir(), '');
        $handle = fopen($tempFile, "w+");
        fwrite($handle,$file);
        fseek($handle, 0);
        $filename = $tempFile;      
        // END -- dealing with fgetcsv() special chars
        $Array = analyse_file($filename, 10);
        $csvDelim = $Array['delimiter']['value'];
        while (($data = fgetcsv($handle, 1000, $csvDelim)) !== FALSE) {
            // process the csv file
        }
    } // end foreach
}