判断UTF-8文本是否全为ASCII?

6
在PHP中,确定给定的UTF-8文本是否纯粹为ASCII的最快方法是什么?
3个回答

15
可能更快的方法是使用负字符类(因为正则表达式只需在遇到第一个字符时停止,无需内部捕获任何内容):
function isAscii($str) {
    return 0 == preg_match('/[^\x00-\x7F]/', $str);
}

没有正则表达式(根据我的评论){
function isAscii($str) {
    $len = strlen($str) {
    for ($i = 0; $i < $len; $i++) {
        if (ord($str[$i]) > 127) return false;
    }
    return true;
}

但我必须问一下,你为什么这么关心速度呢?使用更易读和易理解的版本,只有当你确定它是个问题时才考虑优化它...
编辑:
另一个选择是mb_check_encoding
function isAscii($str) {
    return mb_check_encoding($str, 'ASCII');
}

这将经常运行在大量文本上,我认为这两个选项都很易读,所以速度肯定更重要。 - philfreo
@philfreo:更新了一个答案...但是你最好的方法是使用你的条件实际测试这些选项,以确定哪个最快... - ircmaxell
但是显然 PHP 的 ord 函数在处理 UTF-8 时存在问题。 - barlop
1
不,ord()总是一个单字节的“该字节的值”函数。 - ircmaxell
1
请注意,mb_check_encoding非常慢,而preg_match方法总是更快。 - Fleshgrinder
__基准测试__(对于小型ASCII字符串):正则表达式是最快的方法。for循环和mb_check_encoding要慢大约7倍。 - undefined

2
检查是否有任何字节大于0x7f,或任何字符超过U+007F。

1
非常简单的代码:$isNotAscii = false; for ($i=0,$len=strlen($string);$i<$len;$i++) { if (ord($string[$i]) > 127) { $isNotAscii = true; break; } }。它遍历字符串中的每个字符,查找大于127的字符... - ircmaxell
1
我相信在这种情况下preg_match会更快...虽然没有进行基准测试,但对于字符串模式匹配来说,它几乎总是更快的。 - Zathrus Writer

1
function isAscii($str) {
    return preg_match('/^([\x00-\x7F])*$/', $str);
}

// doesn't accept ASCII control characters
function isAsciiText($str) {
    return preg_match('/^([\x09\x0A\x0D\x20-\x7E])*$/', $str);
}

这将在一些有效的ASCII控制字符上失败。 - bcosca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接