我有一个杂乱的数据库,其中包含世界各地许多机构的名称。
我想显示它们,包括国家字符,但没有无效字符 - 在firefox中显示为unicode数字。
如何过滤掉它们?
数据库有utf8编码,但是某些字符串插入了错误的编码,或者已经在源代码中出现问题。
我不想修复数据库 - 它太大了。我想过滤掉它 - “看不见了”
答案 0 :(得分:6)
我想过滤掉它
您的数据有一个未指定的编码/字符集。这是一个很大的问题。
您可以先尝试将其转换为utf-8
,然后删除所有不可打印的字符:
$str = iconv('utf-8', 'utf-8//ignore', $str);
echo preg_replace('/[^\pL\pN\pP\pS\pZ]/u', '', $str);
问题是,iconv
功能只能尝试。它会丢弃任何无效的字符序列。从PHP 5.4开始,如果指定的输入编码无效,它将删除完整的字符串。
从PHP 5.3开始,您将看到警告输入字符串的编码无效。
您可以先删除所有无效utf-8
字节序列来解决此问题:
$str = valid_utf8_bytes($str);
echo preg_replace('/[^\pL\pN\pP\pS\pZ]/u', '', $str);
/**
* get valid utf-8 byte squences
*
* take over all matching bytes, drop an invalid sequence until first
* non-matching byte.
*
* @param string $str
* @return string
*/
function valid_utf8_bytes($str)
{
$return = '';
$length = strlen($str);
$invalid = array_flip(array("\xEF\xBF\xBF" /* U-FFFF */, "\xEF\xBF\xBE" /* U-FFFE */));
for ($i=0; $i < $length; $i++)
{
$c = ord($str[$o=$i]);
if ($c < 0x80) $n=0; # 0bbbbbbb
elseif (($c & 0xE0) === 0xC0) $n=1; # 110bbbbb
elseif (($c & 0xF0) === 0xE0) $n=2; # 1110bbbb
elseif (($c & 0xF8) === 0xF0) $n=3; # 11110bbb
elseif (($c & 0xFC) === 0xF8) $n=4; # 111110bb
else continue; # Does not match
for ($j=++$n; --$j;) # n bytes matching 10bbbbbb follow ?
if ((++$i === $length) || ((ord($str[$i]) & 0xC0) != 0x80))
continue 2
;
$match = substr($str, $o, $n);
if ($n === 3 && isset($invalid[$match])) # test invalid sequences
continue;
$return .= $match;
}
return $return;
}
答案 1 :(得分:1)
数据库可能不完全是问题 - 如果表是utf8编码的,那么它们中的字符串应该被转换(我认为)。我遇到的问题是正确确保编码是一致的。例如,默认情况下,mysqli连接器恢复为Latin-8859 IIRC,因此很可能在utf8中输出输出,utf8中的数据库仍然最终?字符,因为它们被mysqli连接器转换为拉丁语。
要确保全面的utf8,您需要执行以下操作:
在数据库中:
确保整理类似于utf8_general_ci
位于PHP视图文件的顶部:
<?php header('Content-Type:Text/Plain;charset=utf-8'); ?>
在HTML元标记中(可选):
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
AND在数据库连接器中(以MySQLi为例):
mysqli::set_charset('utf8'); #note that for MySQL it isn't hyphenated
您可能会发现无论如何都能解决问题。
答案 2 :(得分:0)
如果数据库是你的情况下的问题(并且修复它就不在了),那么可能只是使用ORD打印出字符串中的每个字符,并找到不是控制字符的值好的。
然后,当您知道控制字符值时,将这些值传递给搜索该控制字符的函数,并尝试使用相应的UTF8字符更改utf-8编码(有缺陷的编码)。