PHP截取字串長度(中英文混合字串)

來源:互聯網
上載者:User

取部份字串。

文法: string substr(string string, int start, int [length]);

傳回值: 字串

函數種類: 資料處理

內容說明

本函數將字串 string 的第 start 位起的字串取出 length 個字元。若 start 為負數,則從字串尾端算起。若可省略的參數 length 存在,但為負數,則表示取到倒數第 length 個字元。

使用範例

 代碼如下 複製代碼

<?
echo substr("abcdef", 1, 3);  // 返回 "bcd"
echo substr("abcdef", -2);    // 返回 "ef"
echo substr("abcdef", -3, 1); // 返回 "d"
echo substr("abcdef", 1, -1); // 返回 "bcde"
?>

上面只支援英文不支援中文


截取GB2312中文字串

 代碼如下 複製代碼

< ?php 
 //截取中文字串
 function mysubstr($str, $start, $len) {
     $tmpstr = "";
     $strlen = $start + $len;
     for($i = 0; $i < $strlen; $i++) {
         if(ord(substr($str, $i, 1)) > 0xa0) {
             $tmpstr .= substr($str, $i, 2);
             $i++;
         } else
             $tmpstr .= substr($str, $i, 1);
     }
     return $tmpstr;
 }
 ?>

截取utf8編碼的多位元組字串

 代碼如下 複製代碼

< ?php
 //截取utf8字串
 function utf8Substr($str, $from, $len)
 {
     return preg_replace('#^(?:[x00-x7F]|[xC0-xFF][x80-xBF]+){0,'.$from.'}'.
                        '((?:[x00-x7F]|[xC0-xFF][x80-xBF]+){0,'.$len.'}).*#s',
                        '$1',$str);
 }
 ?>

/*
    * 功能: 作用跟substr一樣,除了它不會造成亂碼
    * 參數:
    * 返回:
    */
 

 代碼如下 複製代碼

   function utf8_substr( $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;
                }
            }
        }

        return $res;
    }

測試資料::

 代碼如下 複製代碼
<?php
    $str = 'dfjdjf測13f試65&2資料fdj(1就mfe&……就';
    var_dump( utf8_substr( $str , 22 , 12 ) );  echo ' <br /> ';
    var_dump( utf8_substr( $str , 22 , -6 ) ); echo ' <br /> ';
    var_dump( utf8_substr( $str , 9 , 12 ) ); echo ' <br /> ';
    var_dump( utf8_substr( $str , 19 , 12 ) ); echo ' <br /> ';
    var_dump( utf8_substr( $str , 28 , -6 ) ); echo ' <br /> ';

顯示結果::(截取無亂碼, 歡迎大家測試, 提交bug)
string(12) "據fdj"
string(26) "據fdj(1就mfe&…"
string(13) "13f試65&2數"
string(12) "資料fd"
string(20) "dj(1就mfe&…"

把我常用的分享出來

下面我們再來看中文截函數吧。

 代碼如下 複製代碼

function MooCutstr($string, $length, $dot = ' ...') {
 global $charset;

 if(strlen($string) <= $length) {
  return $string;
 }
 $string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;'), array('&', '"', '<', '>'), $string);
 $strcut = '';
 if(strtolower($charset) == 'utf-8') {
  $n = $tn = $noc = 0;
  while($n < strlen($string)) {
   $t = ord($string[$n]);
   if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
    $tn = 1; $n++; $noc++;
   } elseif (194 <= $t && $t <= 223) {
    $tn = 2; $n += 2; $noc += 2;
   } elseif (224 <= $t && $t < 239) {
    $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($noc >= $length) {
    break;
   }
  }
  if($noc > $length) {
   $n -= $tn;
  }
  $strcut = substr($string, 0, $n);
 } else {
  for($i = 0; $i < $length; $i++) {
   $strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
  }
 }
 //$strcut = str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);

 return $strcut.$dot;
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.