gpt4 book ai didi

php - 不使用 preg_match() 在 PHP 中进行 UTF-8 验证

转载 作者:可可西里 更新时间:2023-11-01 13:42:21 25 4
gpt4 key购买 nike

我需要验证一些以 UTF-8 编码的用户输入。许多人推荐使用以下代码:

preg_match('/\A(
[\x09\x0A\x0D\x20-\x7E]
| [\xC2-\xDF][\x80-\xBF]
| \xE0[\xA0-\xBF][\x80-\xBF]
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
| \xED[\x80-\x9F][\x80-\xBF]
| \xF0[\x90-\xBF][\x80-\xBF]{2}
| [\xF1-\xF3][\x80-\xBF]{3}
| \xF4[\x80-\x8F][\x80-\xBF]{2}
)*\z/x', $string);

这是一个取自http://www.w3.org/International/questions/qa-forms-utf-8的正则表达式.一切正常,直到我发现 PHP 中的一个错误,该错误似乎至少从 2006 年就存在了。如果 $string 太长,Preg_match() 会导致段错误。似乎没有任何解决方法。您可以在此处查看错误提交:http://bugs.php.net/bug.php?id=36463

现在,为了避免使用 preg_match,我创建了一个函数,它的作用与上面的正则表达式完全相同。我不知道这个问题在 Stack Overflow 上是否合适,但我想知道我所做的功能是否正确。在这里:

编辑 [13.01.2010]:如果有人感兴趣,我发布的先前版本中有几个错误。下面是我的函数的最终版本。

function check_UTF8_string(&$string) {
$len = mb_strlen($string, "ISO-8859-1");
$ok = 1;

for ($i = 0; $i < $len; $i++) {
$o = ord(mb_substr($string, $i, 1, "ISO-8859-1"));

if ($o == 9 || $o == 10 || $o == 13 || ($o >= 32 && $o <= 126)) {

}
elseif ($o >= 194 && $o <= 223) {
$i++;
$o2 = ord(mb_substr($string, $i, 1, "ISO-8859-1"));
if (!($o2 >= 128 && $o2 <= 191)) {
$ok = 0;
break;
}
}
elseif ($o == 224) {
$o2 = ord(mb_substr($string, $i + 1, 1, "ISO-8859-1"));
$o3 = ord(mb_substr($string, $i + 2, 1, "ISO-8859-1"));
$i += 2;
if (!($o2 >= 160 && $o2 <= 191) || !($o3 >= 128 && $o3 <= 191)) {
$ok = 0;
break;
}
}
elseif (($o >= 225 && $o <= 236) || $o == 238 || $o == 239) {
$o2 = ord(mb_substr($string, $i + 1, 1, "ISO-8859-1"));
$o3 = ord(mb_substr($string, $i + 2, 1, "ISO-8859-1"));
$i += 2;
if (!($o2 >= 128 && $o2 <= 191) || !($o3 >= 128 && $o3 <= 191)) {
$ok = 0;
break;
}
}
elseif ($o == 237) {
$o2 = ord(mb_substr($string, $i + 1, 1, "ISO-8859-1"));
$o3 = ord(mb_substr($string, $i + 2, 1, "ISO-8859-1"));
$i += 2;
if (!($o2 >= 128 && $o2 <= 159) || !($o3 >= 128 && $o3 <= 191)) {
$ok = 0;
break;
}
}
elseif ($o == 240) {
$o2 = ord(mb_substr($string, $i + 1, 1, "ISO-8859-1"));
$o3 = ord(mb_substr($string, $i + 2, 1, "ISO-8859-1"));
$o4 = ord(mb_substr($string, $i + 3, 1, "ISO-8859-1"));
$i += 3;
if (!($o2 >= 144 && $o2 <= 191) ||
!($o3 >= 128 && $o3 <= 191) ||
!($o4 >= 128 && $o4 <= 191)) {
$ok = 0;
break;
}
}
elseif ($o >= 241 && $o <= 243) {
$o2 = ord(mb_substr($string, $i + 1, 1, "ISO-8859-1"));
$o3 = ord(mb_substr($string, $i + 2, 1, "ISO-8859-1"));
$o4 = ord(mb_substr($string, $i + 3, 1, "ISO-8859-1"));
$i += 3;
if (!($o2 >= 128 && $o2 <= 191) ||
!($o3 >= 128 && $o3 <= 191) ||
!($o4 >= 128 && $o4 <= 191)) {
$ok = 0;
break;
}
}
elseif ($o == 244) {
$o2 = ord(mb_substr($string, $i + 1, 1, "ISO-8859-1"));
$o3 = ord(mb_substr($string, $i + 2, 1, "ISO-8859-1"));
$o4 = ord(mb_substr($string, $i + 3, 1, "ISO-8859-1"));
$i += 5;
if (!($o2 >= 128 && $o2 <= 143) ||
!($o3 >= 128 && $o3 <= 191) ||
!($o4 >= 128 && $o4 <= 191)) {
$ok = 0;
break;
}
}
else {
$ok = 0;
break;
}
}

return $ok;
}

是的,它很长。我希望我已经正确理解正则表达式的工作原理。也希望对其他人有所帮助。

提前致谢!

最佳答案

您始终可以使用 Multibyte String Functions :

如果您想经常使用它并可能在某个时候更改它:

1) 首先在你的配置文件中设置你想要使用的编码

/* Set internal character encoding to UTF-8 */
mb_internal_encoding("UTF-8");

2) 检查字符串

if(mb_check_encoding($string))
{
// do something
}

或者,如果您不打算更改它,您始终可以将编码直接放入函数中:

if(mb_check_encoding($string, 'UTF-8'))
{
// do something
}

关于php - 不使用 preg_match() 在 PHP 中进行 UTF-8 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1282986/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com