星期四, 元月 21, 2010

PHP 將 UTF-8 的 字串 依 指定長度 切割成陣列(str_split 的 UTF-8版)

PHP 的 str_split() 的功能、使用方式 如下:

<?php
$str = 'Hello';
print_r(str_split($str)); // array('H', 'e', 'l', 'l', 'o')
print_r(str_split($str, 3)); // array('Hel', 'lo')
?>

str_split() 可以將 字串 依 需要的長度 做分割, 但是對 UTF-8 的中文, 就無法切依需要的長度來做切割, 要自己另外處理.

註: 下述程式 使用方法 都跟 str_split() 一樣.

str2_split(): mb_strlen() + mb_substr()

直覺的使用 mb_strlen() + mb_substr() 來寫 UTF-8 版, 對於文字短的狀況, 速度都還夠快.

<?php
function str2_split($string, $split_len = 1)
{
    $len = mb_strlen($string, 'UTF-8');
    if ($len > $split_len || !$split_len) {
        for ($i = 0; $i < $len; $i++) {
            $parts[] = mb_substr($string, 0, $split_len, 'UTF-8');
            $string  = mb_substr($string, $split_len, $len, 'UTF-8');
        }
    } else {
        $parts = array($string);
    }
 
    return $parts;
}
?>

utf8_str_split() - 取自 Joomla - pasamio

後來想想, 這個應該早就有人寫過, 而且一定比上面的好又快, 於是找找 str_split utf-8, 第一筆就找到 Joomla 的 utf8_str_split(). XD

下述轉載自: File source for str_split.php

<?php
/**
* @version $Id: str_split.php 10381 2008-06-01 03:35:53Z pasamio $
* @package utf8
* @subpackage strings
*/
function utf8_str_split($str, $split_len = 1)
{
    if (!preg_match('/^[0-9]+$/', $split_len) || $split_len < 1)
        return FALSE;
 
    $len = mb_strlen($str, 'UTF-8');
    if ($len <= $split_len)
        return array($str);
 
    preg_match_all('/.{'.$split_len.'}|[^\x00]{1,'.$split_len.'}$/us', $str, $ar);
 
    return $ar[0];
}
?>

速度測試

  • 將這兩個 function 各跑 10000次, 看看所使用的時間, 很明顯 utf8_str_split() 比 str2_split() 快了 3倍多~ :)
    • utf8_str_split .. (0.225438117981 secs).
    • str2_split ...... (0.738878965378 secs). 

相關標籤

this is comment icon 如果server 不支持 mb_string呢? [回覆]

如果server 不支持 mb_string呢?

如何把中(亞洲文字)英(希臘文字)準確分割出來 和 計算出長度

Comment by kui (01/23/2010 07:57)

this is comment icon 回 kui [回覆]

有幾種做法:
1. http://zh.wikipedia.org/wiki/UTF-8 看 UTF-8 編碼規則寫.
2. 是 a-z, 0-9 .. 等 希臘文字獨立抽, 非獨立文字的結合起來 - Big5 固定 2bytes, UTF-8 3bytes (註: UTF-8 3~4bytes, 但是 4bytes 我現在還沒遇到過.)
這樣子長度也就可以計算出來囉~ :)

Comment by Tsung (01/23/2010 10:30)
Add this page to del.icio.us

發表迴響

標題

內容 (限制 1000 字)

暱稱

電子郵件

個人網頁


 authimage


PS: 若無法留言, 請先確認是否有打開 JavaScript, 造成您的困擾, 實在萬分對不起 Orz...(如果無法留言, 勞煩可以發信給我好嗎? 謝謝.)
PS2: 若您的留言被誤判, 我都會再自行看過, 不需要一直重覆張貼~