Курилка.co.ua
Orphus RSS kurilka.co.ua

Category

Archives

Урезание строки по словам

Author wmas wmas | Category Category PHP

Здравствуйте, уважаемые читатели моего блога. Борьба за красивости всегда актуальна. Все эти виджеты, плагины и т.д. внесли свою лепту. Их содержание может быть различным и приходится как-то урезать. К примеру, используя фреймами, javascript или PHP (если есть такая возможность). При этом, каждый из вариантов имеет как плюсы так и минусы. В случае с PHP и кодировкой UTF-8, использование функции substr() приводит к не самому лучшему результату.

Проблема собственно в том, что юникодовский текст занимает больше байт, чем количество символов. Поэтому обычный substr() и т.п. могут обрезать текст по служебному байту, что приводит к отображению браузером знака вопроса в конце текста. Все это не очень красиво.
источник: Корректное урезание строк по словам в PHP (maxsite.org)

Другими словами, надо искать обходные пути. В своём варианте я предлагаю резать по количеству слов. Основываясь на том, что разбиение строк по пробелу, не приводит к выше упомянутым негативным последствиям.

$max = 5;
$words = split(" ", $str);
if ( count($words)>$max ) $str = join(" ", array_slice($words, 0, $max)) . '...';

Здесь переменная $max - ограничение количество слов в строке, $str - сама строка, $words - массив слов (условно) из которых состоит строка (при этом разделителем служит - пробел). Если количество элементов массива ($words) больше нашего ограничения ($max) мы производим урезание благодаря функции array_slice(), которая производит выборку первых $max элементов массива $words. Полученный результат соединяем в строку (разделитель все тот же – пробел), в конец ставим троеточие и присваиваем $str.

Правда, есть определённые сомнение относительно функции split(). Если у вас возникли с ней проблемы попробуйте explode ;)

Как вы видите все достаточно просто. У нас нет проблем с кусочками слов и т.д. На этом всё. Спасибо за внимание.

Альтернативные варианты

Имхо наиболее интересный и правильный вариант от CTapbIu:

$max = 100;
if (preg_match('/([^ \n\r]+[ \n\r]+){1,'.$max.'}/s', $str, $match)) $str = $match[0].'...';

Правильный вариант с учетом подключенного в PHP модуля mbstring от wert2all, от кого узнал тот и первый :)

$max = 100;
if ( mb_strlen($str, 'utf-8')>$max ) $str = mb_substr($str,0,$max,'utf-8').'...';

Вариант от Максима, по крайне мере впервые я об этом узнал от него:

$max = 100;
$str = iconv('windows-1251','utf-8',$str);
if ( strlen($str)>$max ) $str = substr($str,0,$max).'...';
$str = iconv('utf-8','windows-1251',$str);

Publish: Четверг Дек 13, 2007

8 Responses for "Урезание строки по словам"

feed for comments on this post

  • Комментарий #728 author: wert2all Reply
    publish: Суббота Дек 15, 2007 at 11:36 пп

    К примеру, я заметил, что строки в UTF-8 кодировке плохо поддаются урезанию. Выползают кракозябрики и это не очень приятно. Т.е. использование простого substr тут не покатит.

    А для таких вот вещей в PHP есть давно mb_substr. Да и mb_strlen тоже лутше использовать вместо strlen. ТОлько в шестой версии починят всю проблему с уникодом.

  • Комментарий #729 author: wmas Reply
    publish: Понедельник Дек 17, 2007 at 11:57 пп

    Век живи век учись :D Спасибо за подсказку!
    Правда есть один нюанс. Не знаю как в том же PHP5, но в старых версиях вроде как нужно подключать модуль mbstring. Так что оставлю заметку как альтернативное решение… на всякий случай.

    P.S. на счет антиспама что есть то есть ничто не совершенно :(

  • Комментарий #727 author: wert2all Reply
    publish: Вторник Дек 18, 2007 at 12:02 дп

    Да везде надо подключать mbstring, но на большенстве хостингов он стоит.

    +Не уверен, что будут правильно работать все ваши конструкции с substr и strlen в варианте с юникодом. Ведь эти функции по определению не работают в UTF.

  • Комментарий #730 author: wmas Reply
    publish: Вторник Дек 18, 2007 at 12:16 дп

    2wert2all подловил на хаке с очистки мусора в конце строки :) уберу из заметки, а то народ не помет. Еще раз спасибо. Сам пример работает без substr и strlen 8)

  • Комментарий #731 author: wert2all Reply
    publish: Вторник Дек 18, 2007 at 12:31 дп

    Этого мало ))) Таки split использовать нельзя. Если уже есть mb_split, то это понятно, что проблема существует. А вот explode нормально разобьёт.

    Думаю, совмесными усилиями таки пролечили функцию )

  • Комментарий #732 author: wmas Reply
    publish: Вторник Дек 18, 2007 at 12:40 дп

    2wert2all вообще-то у меня работает и без проблем. Может это символа пробела не затрагивает? Но внесу уточнения ;)

  • Комментарий #733 author: wert2all Reply
    publish: Вторник Дек 18, 2007 at 12:57 дп

    Ну я не спорю. Но если уже писать, то писать правильно. Возможно, пробел и не самое большое мировое зло, но благодаря тому, что вы знаете о split, в будущем проблемы будут вас обходить.

    Я буквально сегодня попал в просак с ord и chr, хотя в мане функций mb_ord не существует ;) Пришлось писать костыли.

    Короче, очень плохо в PHP c юникодом.

  • Комментарий #734 author: wmas Reply
    publish: Вторник Дек 18, 2007 at 1:00 дп

    мне вариант с preg_match понравился больше. В общем, кто хочет тот прорвется ;) Главное думать, потом еще раз думать, ну там можно еще на всякий случай подумать, потом пробовать и делать 8) наверно так.


Popular links

Copyright © since 2006 Курилка.co.ua,
powered by WordPress