/**
* 字符串基础工具
* @author JerryLi
* @version 20210724
*/
class StringBaseTool{
/**
* 截断字符串,保持固定的暂用字节长度
* @param string $sStr 源字符串
* @param int $iMaxLen 保留字节长度
* @param string $sRepStr 替换字符串
* @return string
*/
static public function cutStrKeepByte(string $sStr, int $iMaxLen, string $sRepStr='...'): string{
$iReplen = strlen($sRepStr);
if (strlen($sStr) > $iMaxLen){ //字节数数超长,需要裁剪
$iMaxLen -= $iReplen; //保留拖尾替换字符长度
$aBuf = [];
$iByteLen = 0;
for ($i=0,$iLoop=mb_strlen($sStr); $i<$iLoop; $i++){
$sChr = mb_substr($sStr, $i, 1); //每次取一个字
if (($iByteLen + strlen($sChr)) <= $iMaxLen){ //未到执行长度,继续追加
$aBuf[] = $sChr;
$iByteLen += strlen($sChr); //长度计数
}else{ //长度符合结束提取
return implode($aBuf) . $sRepStr;
}
}
}
return $sStr; //原样返回
}
/**
* 清理字符串内的utf8mb4字符集
* @param string $sSrc 原始数据
* @param string $sReplace 替换符
* @return string
*/
static public function clearUtf8mb4(string $sSrc, string $sReplace='?'): string{
return preg_replace(
'%(?:
\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', $sReplace, $sSrc);
}
/**
* 检查是否包含utf8mb4字符集
* @param string $sSrc 原始数据
* @return bool
*/
static public function isExistUtf8mb4(string $sSrc): bool{
return preg_match(
'%(?:
\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', $sSrc) > 0;
}
}
字节上代码,原理就不细说了,都是生产环境的代码。
isExistUtf8mb4 用来检测是否包含Utf8mb4字符。clearUtf8mb4用来清理Utf8mb4字符。
顺便补个原理吧:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx ,即最高字节具有240或更高的值.如果字符串中有任何这样的字节,则它是4字节序列的指示符,发现这种结构的标志就可以认为是utf8mb4.
|