我正在阅读并解析一个ANSI文件的CSV文件。在我解析它之前,我想删除不在白名单中的任何字符
// remove any odd characters from string
$match_list = "\x{20}-\x{5f}\x{61}-\x{7e}"; // basic ascii chars excluding backtick
$match_list .= "\x{a1}-\x{ff}"; // extended latin 1 chars excluding control chars
$match_list .= "\x{20ac}\x{201c}\x{201d}"; // euro symbol & left/right double quotation mark (from Word)
$match_list .= "\x{2018}\x{2019}"; // left/right single quotation mark (from word)
$cleaned_line = preg_replace("/[^$match_list]/u", "*",$linein);
问题是当它到达一个包含ó(急性o)字符的行时它返回NULL。根据我的文本编辑器,这是xF3所以应该被允许。
为什么在preg_replace中抛出错误?
更新 - 它似乎与文件有关 - 如果我将问题行从CSV文件复制并粘贴到我的PHP文件中,它就可以正常工作。
更新2 - 使用preg_last_error()我能够确定错误是:
PREG_BAD_UTF8_ERROR Returned by preg_last_error() if the last error was caused by malformed UTF-8 data (only when running a regex in UTF-8 mode).
我的文本编辑器刚刚将该文件报告为ANSI,但使用unix file命令我得到了这个:
% file PRICE_LIST_A.csv
PRICE_LIST_A.csv: Non-ISO extended-ASCII text, with CRLF line terminators
% file DOLLARS_PRICE_LIST.csv
DOLLARS_PRICE_LIST.csv: ISO-8859 text, with CRLF line terminators
% file PRICE_LIST_B.csv
PRICE_LIST_B.csv: Non-ISO extended-ASCII text, with CRLF line terminators
% file PRICE_LIST_TEST.csv
PRICE_LIST_TEST.csv: ASCII text, with CRLF line terminators
所以我似乎从同一个会计应用程序中提供了各种编码的文件。我猜这些都不是有效的Unicode
答案 0 :(得分:0)
使用$linein
(PCRE_UTF8修饰符)时,无效的主题/u
将不匹配任何内容。要解决此问题,请确保您传递的字符串为UTF-8。
如果您的字符串是使用ISO-8859-1编码的,请尝试将其转换为UTF8:
$cleaned_line = preg_replace( "/[^$match_list]/u", "*", utf8_encode($linein) );
否则,请检查mb_convert_encoding()函数。