直接上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
/**
* 完整词的截取
*
* @param $str
* @param $start
* @param $length
*
* @return string
*/
public static function usubstr( $str , $start , $length = null)
{
// 先正常截取一遍.
$res = substr ( $str , $start , $length );
$strlen = strlen ( $str );
/* 接着判断头尾各6字节是否完整(不残缺) */
// 如果参数start是正数
if ( $start >= 0) {
// 往前再截取大约6字节
$next_start = $start + $length ; // 初始位置
$next_len = $next_start + 6 <= $strlen ? 6 : $strlen - $next_start ;
$next_segm = substr ( $str , $next_start , $next_len );
// 如果第1字节就不是 完整字符的首字节, 再往后截取大约6字节
$prev_start = $start - 6 > 0 ? $start - 6 : 0;
$prev_segm = substr ( $str , $prev_start , $start - $prev_start );
} // start是负数
else {
// 往前再截取大约6字节
$next_start = $strlen + $start + $length ; // 初始位置
$next_len = $next_start + 6 <= $strlen ? 6 : $strlen - $next_start ;
$next_segm = substr ( $str , $next_start , $next_len );
// 如果第1字节就不是 完整字符的首字节, 再往后截取大约6字节.
$start = $strlen + $start ;
$prev_start = $start - 6 > 0 ? $start - 6 : 0;
$prev_segm = substr ( $str , $prev_start , $start - $prev_start );
}
// 判断前6字节是否符合utf8规则
if (preg_match( '@^([x80-xBF]{0,5})[xC0-xFD]?@' , $next_segm , $bytes )) {
if (! empty ( $bytes [1])) {
$bytes = $bytes [1];
$res .= $bytes ;
}
}
// 判断后6字节是否符合utf8规则
$ord0 = ord( $res [0]);
if (128 <= $ord0 && 191 >= $ord0 ) {
// 往后截取 , 并加在res的前面.
if (preg_match( '@[xC0-xFD][x80-xBF]{0,5}$@' , $prev_segm , $bytes )) {
if (! empty ( $bytes [0])) {
$bytes = $bytes [0];
$res = $bytes . $res ;
}
}
}
if ( strlen ( $res ) < $strlen ) {
$res = $res . '...' ;
}
return $res ;
}
|