今天我决定测试一个小函数,检查字符串是否为UTF-8。
我使用Multilingual form encoding的推荐并创建了一个小帮手:
function is_utf8($string) {
if (strlen($string) == 0)
{
return true;
}
return preg_match('%^(?:
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*$%xs', $string);
}
作为测试,我使用了一个包含196个字符的字符串。然后检查了我的助手。但是浏览器不会显示带有结果的页面 - 而是找不到404页面。
$string = "1234567890123456789012345678..."; // 196 characters here
echo strlen($string); // result - 196
var_dump(is_utf8($string)); // Error - Page not found!
但如果我使用195个字符,一切正常。
我尝试过任何角色,甚至是空格。此函数仅适用于不超过195个字符的字符串。
为什么?
答案 0 :(得分:1)
这也适用于简单的正则表达式和序列化
function check_utf8($str) {
return (bool)preg_match('//u', serialize($str));
}
答案 1 :(得分:1)
做了一个简单的测试。 我执行了1000000次的功能。看谁更快。 我还要感谢@mario提供原子分组的帮助。
$string = "ывлдоkfdsuLIU(*knj4k58u7MJHKkiyhsf9hfhlknhlkjldfivjo8iulkjlgs".
"2345678901234567890123456789012345678901234567890123456789012".
"ыдваолт ДЛЯОЧДльы0щ39478509г0*()*?Щчялртодылматцю4к 2ылвсголо".
"4567890123456789012345678901234567890123456789012345678901234".
"4567890123456789012345678901234567890123456789012345678901234".
"asdfsd ds.kjasldasjlKUJLjLKZjulizL kzjxLkUJOLIULKM.LKl;.mcvss";
$s = microtime(true);
for ($i=0; $i<1000000; $i++)
{
// algorithm
}
$e = microtime(true);
echo $e-$s;
结果如下:
preg_match('//u', $string )
结果: 11.634791135788 秒
(preg_match('%^(?>
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*$%xs', $string)
结果:致命错误:超过最长执行时间30秒
preg_match('/^./su', $string)
结果: 12.27244400978 秒
mb_detect_encoding($string, array('UTF-8'), true)
结果: 15.370143890381 秒
我也尝试过@helloworld
提出的方法preg_match('//u', serialize($string))
结果: 23.193331956863 sec
谢谢大家的意见! 你帮我理解了
答案 2 :(得分:1)
如果字符串太长 - &gt; PCRE崩溃
查看http://www.java-samples.com/showtutorial.php?tutorialid=1526以解决问题