威尼斯正规官网那边探讨的字符串截取难点都是指向UTF-8编码的中文字符串,strlen是求字符串长度的函数'
分类:博客热点

咱俩精通有的时候候使用substr来截取UTF-8粤语字符串的时候,日常汇合世乱码,为何会身不由己这么的标题吧,本布告诉您答案。
看这么大器晚成段代码吧(字符编码为UTF-8): 复制代码 代码如下:

下边先交付八个版本函数的源代码甚至简单测量检验,最后笔者会给出三个实用性更加强的字符串截取函数。需求小心的是:这里钻探的字符串截取难点都以指向性UTF-8编码的华语字符串。 discuz版本 复制代码 代码如下: /** * [discuz] 基于PHP未有设置 mb_substr 等扩充截取字符串,假若截取汉语字则按2个字符总括 * @param $string 要截取的字符串 * @param $length 要截取的字符数 * @param $dot 替换截掉部分的结尾字符串 * @return 重回截取后的字符串 */ function cutstr($string, $length, $dot = '...'卡塔尔(قطر‎ { // 假若字符串小于要截取的长度则直接回到 // 此处使用strlen获取字符串长度有相当大的流弊,比方对字符串“新岁快乐”要截取4个粤语字符, // 那么必需明白那4个汉语字符的字节数,否则重临的字符串恐怕会是“春节开心...” if <= $length卡塔尔 { return $string; } // 调换原字符串中htmlspecialchars $pre = chr; $string = str_replace ( array ('&', '"', '' 卡塔尔国, array ($pre . '&' . $end, $pre . '"' . $end, $pre . '' . $end 卡塔尔国, $string State of Qatar; $strcut = ''; // 开头化重回值 // 如若是utf-8编码 if (strtolower == 'utf-8'卡塔尔(قطر‎ { // 开端一连循环指针$n,最后多个字位数$tn,截取的字符数$noc $n = $tn = $noc = 0; while ( $n < strlen { $t = ord ; if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126State of Qatar卡塔尔国 { // 要是是德文半角符号等,$n指针后移1位,$tn最后字是1位 $tn = 1; $n++; $noc++; } elseif (194 <= $t && $t <= 223State of Qatar { // 如若是二字节字符$n指针后移2位,$tn最终字是2位 $tn = 2; $n += 2; $noc += 2; } elseif (224 <= $t && $t <= 239卡塔尔国 { // 如若是三字节,$n后移3位,$tn最终字是3位 $tn = 3; $n += 3; $noc += 2; } elseif (240 <= $t && $t <= 247卡塔尔 { $tn = 4; $n += 4; $noc += 2; } elseif (248 <= $t && $t <= 251卡塔尔 { $tn = 5; $n += 5; $noc += 2; } elseif ($t == 252 || $t == 253卡塔尔 { $tn = 6; $n += 6; $noc += 2; } else { $n++; } // 超越了要取的数就跳出三番若干遍循环 if { break; } } // 这些地点是把最后一个字去掉,以备加$dot if { $n -= $tn; } $strcut = substr ; } else { // 并不是utf-8编码的全角就后移2位 for ($i = 0; $i < $length; $i ++State of Qatar { $strcut .= ord > 127 ? $string [$i] . $string [++ $i] : $string [$i]; } } // 再过来最先的htmlspecialchars $strcut = str_replace( array ($pre . '&' . $end, $pre . '"' . $end, $pre . '' . $end 卡塔尔, array ('&', '"', '' 卡塔尔(قطر‎, $strcut 卡塔尔国; $pos = strrpos ; if { $strcut = substr ; } return $strcut . $dot; // 最后把截取加上$dot输出 } discuz版本的最大缺点在于利用 strlen 获取原始字符串的尺寸,并用于和传唱的要截取长度参数举行比较,由于UTF-8的华语字符的字节数是不定点的,所以就能够面前碰着这样的窘况:假设要截取4个中文字符应该钦定多大的截取长度呢?8字节仍旧12字节呢?。。。这是力不从心估摸的,也多亏因为这几个难点discuz的cutstr实际是有bug的,通过上边包车型地铁测量试验结果能见到: 复制代码 代码如下: $str1 = "欲穷千里目"; echo my_cutstr."n"; // 输出:欲穷千里目... [那是三个bug,思考是怎么样来头招致?] echo my_cutstr."n"; // 输出:欲穷千里目 引致上述bug的来头在与cutstr函数在截取字符的时候是将一个汉语字按2个字符算,那么5个中文字就是10字符,而原始字符串的尺寸是15字节,所以cutstr感到“成功地”从15字符的串上截取了十贰个字符,然后加上了“尾巴”。要解决这一个bug只要在认清一下回到的子串是或不是和原始串雷同,如果相像就不加“尾巴”。 ecshop版 复制代码 代码如下: /** * [ecshop] 基于PHP的 mb_substr,iconv_substr 那三个扩大来截取字符串,中文字符都以按1个字符长度计算; * 该函数仅适用于utf-8编码的普通话字符串。 * * @param $str 原始字符串 * @param $length 截取的字符数 * @param $append 替换截掉部分的结尾字符串 * @return 重回截取后的字符串 */ function sub_str($str, $length = 0, $append = '...') { $str = trim; $strlength = strlen; if ($length == 0 || $length >= $strlength) { return $str; } elseif { $length = $strlength

$str = '都知道strlen与mb_strlen是求字符串长度的函数';
echo strlen($str)'.
'.mb_strlen($str,'utf-8');
?>

  • $length; if { $length = $strlength; } } if ( function_exists { $newstr = mb_substr($str, 0, $length, 'utf-8'); } elseif ( function_exists { $newstr = iconv_substr($str, 0, $length, 'utf-8'); } else { //$newstr = trim_right(substr; $newstr = substr; } if ($append && $str != $newstr卡塔尔(قطر‎ { $newstr .= $append; } return $newstr; } ecshop版的特征和破绽都在于将汉语字符算作一个字符,若是原始字符串中不含汉语,比如:abcd1234,如果本意是要截取4此中文字符恐怕8个德语字符,那么使用ecshop的本子就得不到希望的结果,再次来到值的是:abcd。上面是粗略的测量试验结果: 复制代码 代码如下: $str1 = "白日依山尽,黄河入海流"; echo $str1."n"; echo my_sub_str."n"; // 输出:白日依山... $str2 = "白1日2依3山4"; echo $str2."n"; echo my_sub_str."n"; // 输出:白1日2... 优化版 截取汉语字符串的超多用出席景是“原始字符串能够是汉语、意国语、数字混杂的,普通话字按2个字符算,德语数字按1个字符算”,针对这些需要上面给出一个实现版本: 复制代码 代码如下: /** * 字符串截取,汉语字符按2个字符计算,同期协理GBK和UTF-8编码 * @param $string 要截取的字符串 * @param $length 要截取的字符数 * @param $append 加多到子串后的尾巴 * @return 再次来到截取后的字符串 */ function substring($string, $length, $append = false卡塔尔 { if { return ''; } // 检验原始字符串是还是不是为UTF-8编码 $is_utf8 = false; $str1 = @iconv("UTF-8", "GBK", $string); $str2 = @iconv("GBK", "UTF-8", $str1); if { $is_utf8 = true; // 如果是UTF-8编码,则使用GBK编码的 $string = $str1; } $newstr = ''; for ($i = 0; $i < $length; $i ++) { $newstr .= ord > 127 ? $string[$i] . $string[++$i] : $string[$i]; } if { $newstr = @iconv("GBK", "UTF-8", $newstr); } if ($append && $newstr != $string卡塔尔(قطر‎ { $newstr .= $append; } return $newstr; } 测量检验结果见下: 复制代码 代码如下: $str1 = "白日依山尽,恒河入海流"; echo substring."n"; // 输出:白日... echo substring."n"; // 输出:白日依... $str2 = "12白34日56依78山"; echo substring."n"; // 输出:12白... echo substring."n"; // 输出:12白3... 作者:edwardlost' blog

运维上述代码,重返值如下:
66
威尼斯正规官网,34
什么样?strlen中,中文是多个字节的长短,匈牙利(Magyarország卡塔尔国语则是一个字节的长度!mb_strlen中,都被总括为一字节的长短!所以,大家有时用substr来截取UTF-8普通话字符串的时候,日常会产出乱码,正是这一个原因了!
上边提供一个截取UTF-8字符串的函数:
复制代码 代码如下:
function cutstr($sourcestr,$cutlength){
$returnstr = '';
$i = 0;
$n = 0;
$str_length = strlen($sourcestr);
$mb_str_length = mb_strlen($sourcestr,'utf-8');
while(($n < $cutlength) && ($i <= $str_length)){
$temp_str = substr($sourcestr,$i,1);
$ascnum = ord($temp_str);
if($ascnum >= 224){
$returnstr = $returnstr.substr($sourcestr,$i,3);
$i = $i + 3;
$n++;
}
elseif($ascnum >= 192){
$returnstr = $returnstr.substr($sourcestr,$i,2);
$i = $i + 2;
$n++;
}
elseif(($ascnum >= 65) && ($ascnum <= 90)){
$returnstr = $returnstr.substr($sourcestr,$i,1);
$i = $i + 1;
$n++;
}
else{
$returnstr = $returnstr.substr($sourcestr,$i,1);
$i = $i + 1;
$n = $n + 0.5;
}
}
if ($mb_str_length > $cutlength){
$returnstr = $returnstr . "...";
}
return $returnstr;
}

运用例子:
复制代码 代码如下:

$str = '保藏期最长征三号个月,当先有效期系统将自行删除本条音信';
//echo strlen($str);
//echo '


'.mb_strlen($str,'utf-8');
echo '


'.$str;
echo '


'.cutstr($str,24);
?>

本文由威尼斯在线注册平台发布于博客热点,转载请注明出处:威尼斯正规官网那边探讨的字符串截取难点都是指向UTF-8编码的中文字符串,strlen是求字符串长度的函数'

上一篇:如果是中文,smarty会截取到一个词的末尾 下一篇:格式化内容,用户输入数据
猜你喜欢
热门排行
精彩图文