Unicode substr

svdesign

Guest
Unicode substr

Подскажите функцию возвращающую часть строки в кодировке UTF-8.
В мануале такие есть, но iconv_substr появилась только в PHP5, а mb_substr я не хочу привязыватся к модулю mbstring.

Задача у меня простая, вернуть первые несколько букв из Unicode текста. Подойдет реализация такой функции прямо на языке PHP.
 

neko

tеam neko
насколько я нифига не смыслю в этих кодировках

в utf-8
по первым четырем битам можно определить сколькими байтами закодирован символ

0000 для одного
1100 для двух байт
1110 для трех
1111 для четырех

далее посчитать непроблема
если вру, поправьте
 

Profic

just Profic (PHP5 BetaTeam)
man utf8
+ 5 минут писанины (если именно нужно первые символы), т.к. реализация будет довольно простой, ибо utf8 имеет вполне регулярную структуру.
 

svdesign

Guest
Автор оригинала: neko
в utf-8
по первым четырем битам можно определить сколькими байтами закодирован символ

0000 для одного
1100 для двух байт
1110 для трех
1111 для четырех
Что-то в этом есть не то, если втулить в первый байт первые четыре бита одними нулями, то у тебя будет всего 15 символов в алфавите, а должно быть минимум 127 :)
Логично предположить что символы от 0 до 127 кодируются одним байтом, у кого первый бит установлен, т.е. от 128ми, кодируются двумя байтами, но как тогда быть с 3 и 4мя байтами?
 

SiMM

Новичок
Насколько я не смыслю в кодировках, проблема вообще выдуманная, если ознакомиться хотя бы с азами.
Формат UTF-8
PS: правда, признаюсь честно, там не рассматриваются 4х-байтовые коды, однако тенденция вполне просматривается.
 

svdesign

Guest
Автор оригинала: SiMM
Насколько я не смыслю в кодировках, проблема вообще выдуманная, если ознакомиться хотя бы с азами.
Формат UTF-8
PS: правда, признаюсь честно, там не рассматриваются 4х-байтовые коды, однако тенденция вполне просматривается.
Во, другой же табак,
1 байтный символ: 0zzzzzzzz
2х байтный символ: 110yyyyy 10zzzzzz
3х байтный символ: 1110xxxx 10yyyyyy 10zzzzzz

Спасибо за ссылку.
А в чем поблема могу пояснить, вот строка в UTF-8:
Copyright Р?нтернет-агентство
Теперь дай мне первые 15 символов из этой строки также в UTF-8
 

SiMM

Новичок
Непонимаю, в чём проблема ;)
PHP:
function isubstr($str,$from,$len){
  $ret = '';
  for ($i=$j=0; $i<$from+$len; $i++){
    $code = ord($ch=$str[$j++]);
    if ($code > 0xFB) $ch .= $str[$j++];
    if ($code > 0xF7) $ch .= $str[$j++];
    if ($code > 0xEF) $ch .= $str[$j++];
    if ($code > 0xDF) $ch .= $str[$j++];
    if ($code > 0xBF) $ch .= $str[$j++];
    if ($i >= $from) $ret .= $ch;
  }
  return $ret;
}
PS: аналог [m]substr[/m], если забыть о том, что:
1. Нет никакой валидации.
2. $from >= 0
3. $to >= 0
необходимую функциональность предлагаю реализовать своими силами ;)
PPS: некоторые подробности брал отсюда
PPPS: ещё более простое решение можно получить при помощи регулярников ;)
PHP:
function isubstr($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);
}
 

neko

tеam neko
svdesign
ну да ошибся, не по четырем
в любом случае по первым битам
 
Сверху