一个比较好用的字符串截取函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
function substring( $str , $start , $length ){ //比较好用字符串截取函数 $len = $length ; if ( $length < 0){ $str = strrev ( $str ); $len = - $length ; } $len = ( $len < strlen ( $str )) ? $len : strlen ( $str ); $tmpstr = "" ; for ( $i = $start ; $i < $len ; $i ++) { if (ord( substr ( $str , $i , 1)) > 0xa0) { $tmpstr .= substr ( $str , $i , 2); $i ++; } else { $tmpstr .= substr ( $str , $i , 1); } } if ( $length < 0) $tmpstr = strrev ( $tmpstr ); return $tmpstr ; } |
使用方法示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
$str1 = '我是一串比较长的中文不带英文' ; $str2 = '我是一串比较长的中文带yingwen' ; $len = strlen ( $str1 ); echo '<br />' . $len ; //return 28 $len = strlen ( $str2 ); echo '<br />' . $len ; //return 29 echo '<br />' ; echo substring( $str1 , 0, 11); echo '<br />' ; echo substring( $str2 , 0, 11); echo '<br />' ; echo substring( $str1 , 16, 28); echo '<br />' ; echo substring( $str2 , 16, 29); |
结果显示:
28
29
我是一串比较
我是一串比较
中文不带英文
中文带yingwen
这个函数十分有用,比如用来截断比较长的文件名,但是要在中间加上...,可以这样来做:
1
2
3
4
5
6
7
8
9
10
|
function formatName( $str , $size ){ $len = strlen ( $str ); if ( strlen ( $str ) > $size ) { $part1 = substring( $str , 0, $size / 2); $part2 = substring( $str , $len - ( $size /2), $len ); return $part1 . "..." . $part2 ; } else { return $str ; } } |
另外,网上看到一种超级简单的中文截断解决方案,试用了一下,效果也不错:
echo substr($str1,0,10).chr(0);
原理解释:
chr(0)不是null
07null是什么都没有,而chr(0)的值是0。表示成16进制是0x00,表示成二进制是00000000
08虽然chr(0)不会显示出什么,但是他是一个字符。
09当汉字被截断时,根据编码规则他总是要把后边的其他字符拉过来一起作为汉字解释,这就是出现乱码的原因。而值为0x81到0xff与0x00组合始终都显示为“空”
10根据这一特点,在substr的结果后面补上一个chr(0),就可以防止出现乱码了
----------------------------
20120705更新:
以上方法虽好,但是偶尔还是会碰到乱码,原因未深究。不过可以用以下的方法,对UTF8字符文本屡试不爽。
注意:该方法中将汉字计算为1单位长度,英文一个字母1单位长度,所以截断时需要注意长度设置。
计算长度的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
function strlen_UTF8( $str ) { $len = strlen ( $str ); $n = 0; for ( $i = 0; $i < $len ; $i ++) { $x = substr ( $str , $i , 1); $a = base_convert (ord( $x ), 10, 2); $a = substr ( '00000000' . $a , -8); if ( substr ( $a , 0, 1) == 0) { } elseif ( substr ( $a , 0, 3) == 110) { $i += 1; } elseif ( substr ( $a , 0, 4) == 1110) { $i += 2; } $n ++; } return $n ; } // End strlen_UTF8; |
字符串截断函数:
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
|
function subString_UTF8( $str , $start , $lenth ) { $len = strlen ( $str ); $r = array (); $n = 0; $m = 0; for ( $i = 0; $i < $len ; $i ++) { $x = substr ( $str , $i , 1); $a = base_convert (ord( $x ), 10, 2); $a = substr ( '00000000' . $a , -8); if ( $n < $start ){ if ( substr ( $a , 0, 1) == 0) { } elseif ( substr ( $a , 0, 3) == 110) { $i += 1; } elseif ( substr ( $a , 0, 4) == 1110) { $i += 2; } $n ++; } else { if ( substr ( $a , 0, 1) == 0) { $r [ ] = substr ( $str , $i , 1); } elseif ( substr ( $a , 0, 3) == 110) { $r [ ] = substr ( $str , $i , 2); $i += 1; } elseif ( substr ( $a , 0, 4) == 1110) { $r [ ] = substr ( $str , $i , 3); $i += 2; } else { $r [ ] = '' ; } if (++ $m >= $lenth ){ break ; } } } return join( $r ); } // End subString_UTF8; |
使用方法和之前介绍的一样,比如formatName可以实现如下(这对汉字长度做了小优化):
1
2
3
4
5
6
7
8
9
10
11
12
|
function formatName( $str , $size ){ $len = strlen_UTF8( $str ); $one_len = strlen ( $str ); $size = $size * 1.5 * $len / ( $one_len ); if (strlen_UTF8( $str ) > $size ) { $part1 = subString_UTF8( $str , 0, $size / 2); $part2 = subString_UTF8( $str , $len - ( $size /2), $len ); return $part1 . "..." . $part2 ; } else { return $str ; } } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。