substr() и utf-8

peasant

Новичок
substr() и utf-8

При обрезании текста в utf-8 может получиться так, что последняя буква разделится пополам и будет некорректно отображена. Как избежать этого? Неужели надо iconv() переводить текст в скажет win-1251 затем делает substr() затем iconv() обратно в utf-8 и вывод?
 

Rin

*
PHP:
<?php

/**
 * Implementation substr() function for utf-8 encoding string.
 *
 * @param    string  $str
 * @param    int     $offset
 * @param    int     $length
 * @return   string
 *
 * @author   Nasibullin Rinat <n a s i b u l l i n  at starlink ru>
 * @charset  ANSI
 * @link     http://www.w3.org/International/questions/qa-forms-utf-8.html
 * @version  1.0.2
 */
function utf8_substr($str, $offset, $length = null)
{
    #в начале пробуем найти стандартные функции
    if (function_exists('iconv_substr'))
    {
        #(PHP 5)
        return iconv_substr($str, $offset, $length, 'utf-8');
    }
    if (function_exists('mb_substr'))
    {
        #(PHP 4 >= 4.0.6, PHP 5)
        return mb_substr($str, $offset, $length, 'utf-8');
    }
    preg_match_all('~[\x09\x0A\x0D\x20-\x7E]             # ASCII
                     | [\xC2-\xDF][\x80-\xBF]            # non-overlong 2-byte
                     |  \xE0[\xA0-\xBF][\x80-\xBF]       # excluding overlongs
                     | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
                     |  \xED[\x80-\x9F][\x80-\xBF]       # excluding surrogates
                     |  \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', $str, $m);
    if ($length !== null)
    {
        $a = array_slice($m[0], $offset, $length);
    }
    else
    {
        $a = array_slice($m[0], $offset);
    }
    return implode('', $a);
}

?>
 

Wicked

Новичок
Код:
    preg_match_all('~[\x09\x0A\x0D\x20-\x7E]             # ASCII 
                     | [\xC2-\xDF][\x80-\xBF]            # non-overlong 2-byte 
                     |  \xE0[\xA0-\xBF][\x80-\xBF]       # excluding overlongs 
                     | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 
                     |  \xED[\x80-\x9F][\x80-\xBF]       # excluding surrogates 
                     |  \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', $str, $m);
может лучше как-нибудь так? :)
Код:
preg_match_all('~.~us', $str, $m);
 

SiMM

Новичок

Rin

*
Замечание.
Модификатор /u не работает правильно в паре с модификатором /i.
Возможно, в более свежих версиях PHP это исправлено.
 

SiMM

Новичок
> Модификатор /u не работает правильно в паре с модификатором /i.
А здесь он и не требуется.
 
Сверху