• Шаблоны для вашего сайта
  • Сделать сайт
  • Реклама
  • Berry CSS
  • Albireo Framework
  • Бесплатный HTML-курс
  • Telegram-канал
  • Обратная связь
MaxSite.org
О создании сайтов и не только
Создание сайтов под ключ →
Вход
×
или зарегистрироваться

Корректное урезание строк по словам в PHP

PHPПросмотров: 33109Комментарии: 2213 декабря 2007 г.

Все гениальное не просто, а очень просто! Константин придумал способ как корректно обрезать текст по словам причем без использвания строковых функций.

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

До недавнего времени я вынужден был вообще пойти на крайнее извращение и перед использованием str_функций преобразовывал текст в windows-1251, выполнял нужные операции, а потом кодировал обратно в utf-8.

Константин сделал совсем просто: строка разбивается в массив (которые уже корректно работают с utf-8), массив обрезается, а потом объединяется в строку. Все элементарно. :)

Вот немного модифицированная функция для таких случаев:

function maxsite_str_word($text, $counttext = 10, $sep = ' ') {
	$words = split($sep, $text);

	if ( count($words) > $counttext )
		$text = join($sep, array_slice($words, 0, $counttext));

	return $text;
}

То есть в ней можно указать сам текст, количество слов и разделитель (это для универсальности).


Создание сайтов (Украина) →
CMS. Теория
Вебальта - шпион?
twitter.com facebook.com
Другие записи сайта
CodeIgniter 4. Основы. Установка
CodeIgniter 4. Основы. Установка
Текстовый редактор PSPad
Текстовый редактор PSPad
Небольшое интервью
Небольшое интервью
Обновление Albireo Framework (январь 2021)
Обновление Albireo Framework (январь 2021)
Отличия MaxSite CMS от WordPress с точки зрения верстки шаблона
Отличия MaxSite CMS от WordPress с точки зрения верстки шаблона
Эволюции WordPress посвящается
Эволюции WordPress посвящается

Комментариев: 22 RSS

1Бресь Сергей13-12-2007 15:58

http://php.net/mb_substr

http://php.net/manual/en/ref.mbstring.php

?

2Dimox13-12-2007 15:58

Жаль, что я в этом нифига не понимаю :mrgreen:

3Бомж без колес13-12-2007 16:07

Ну правильно, разбиваем по пробелам, потом соединяем... У мну тоже где-то подобная функция через регулярку валялась... можно еще поверить знак препинания в конце: если запятая, двоеточие и т.п. - отрезать, ибо неэстетично, но это уже так, изыски...

4Максим13-12-2007 17:27

Тут главное не в том, чтобы разбить по пробелу, а в том, что стандартные str_ некорректно работают с юникодовскими строками. Поэтому нужно либо локаль подключать, либо mbstrings пользоваться. Но не всегда mb включены на серверах, поэтому нужно всегда проверять наличие этих функций перед использованием. При использовании же массива все очень просто, быстро и без проблем с совместимостью.

5CTapbIu13-12-2007 21:51

как вариант:


if (preg_match('/([^ \n\r]+[ \n\r]+){1,10}/s', $text, $match))
$substr = $match[0];

6generator200314-12-2007 00:07

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

А можно пример в коде ???

а то на словах не совсем понятно

7Maksus14-12-2007 00:32

Dimox, чем-то мы с тобой похожи :???:

8Максим14-12-2007 00:33

Вот такой код может неверно обрезать текст:

$TEXT = substr($TEXT, 0, $counttext );

9Охотник на зелёных14-12-2007 15:52

Уже давным давно, когда я только переделывал виджеты, я переделал виджет и "последние комментарии". Мне ещё тогда в дефолтном бесило, что делиться всё по символам, а не по словам. И я переделал виджет. Но у меня почему то и со split-ом была проблема, добавлялось в конце всегда ? (символ пробела видимо не в той кодировке). Вот выдержки из обновлённого виджета latest comments который работает по такому же принципу, что и описывается:

$arr = explode(" ", $comment_content);

$count_arr = count($arr);

$comment_content ="";

if ($max_chars > $count_arr) $max_chars2 = $count_arr;

else $max_chars2 = $max_chars;

for ($i = 0; $i

10Охотник на зелёных14-12-2007 15:54

забыл про эти символы :-)

$arr = explode(" ", $comment_content);

$count_arr = count($arr);

$comment_content ="";

if ($max_chars > $count_arr) $max_chars2 = $count_arr;

else $max_chars2 = $max_chars;

for ($i = 0; $i<$max_chars2; $i++) {

$comment_content .= $arr[$i]." ";

}

if ($max_chars2 != $count_arr) $comment_content .= "...";

11Yantar14-12-2007 16:19

то есть, explode вместо split тоже может сработать некорректно?

12Max14-12-2007 19:09

А почему бы не взять готовую функцию из Drupal? там вообще много всего хорошего уже сделано :Р

13cross14-12-2007 22:24

Идея со сплитом не очень быстродейственная. А ведь есть еще и разные разделительные знаки... :)

14CTapbIu15-12-2007 10:05

а чем же вам не нравятся регэкспы?

15Максим15-12-2007 12:43

2CTapbIu: Вариант с preg_match, тоже хорош.

16Алексей17-12-2007 14:11

Действительно, а чем не устраивают мультибайтовые строковые функции? (как сказано в первом коменте)

http://php.net/manual/en/ref.mbstring.php

Урезание по словам - это не то, что требуется в большинсте случаев, так как фраза из N слов может быть очень разной по длине.

Но если стоит задача именно разбиения по словам, то я бы использовал explode, implode.

17murich17-12-2007 20:00

я бы чесно говоря если надо было бы сразу через массив делал

18Zmei10-01-2008 12:10

Спасибо за статью.

Предлогаю модификацию функции где текст урезается не только по словам , но и по символам в случае если текст длиннннннее заданного количества $maxchar .

Может быть кому нибудь пригодится :mad:

function getPrewText( $text, $maxwords = 30, $maxchar = 300  )
{
$sep = ' '
$words = split( $sep, $text );
$char = iconv_strlen( $text, 'utf-8' );

if ( count( $words ) > $maxwords )
{
$text = join($sep, array_slice($words, 0, $maxwords));
}

if ( $char > $maxchar )
{
$text = iconv_substr( $text, 0, $maxchar, 'utf-8' );
}

return $text;

}

19Аноним05-05-2011 16:19

Метод хороший, только непонятно, что делать, если мне заранее не известно количество слов?

20CrazyTimon22-12-2011 05:51

Как вариант, если используете codeigniter, то есть функция "word_limiter($text, $number_of_world)" хелпера "Text Helper"

21Валера18-12-2012 05:20

Чтобы уже все окончательно встало на свои места,

найдено на просторах интернета:

Для корректной работы с многобайтными кодировками в PHP предусмотрен набор функций, их легко можно узнать по наличию приставки mb_

Рассмотри корректный код усечения строки в многобайтной кодировка:

mb_internal_encoding("UTF-8");       // указываем нужную кодировку
mb_substr( 'Тестовая строка', 0, 4); // выполняем преобразование строки

Операция усечения выполняется в два этапа, сначала задается кодировка строки и только после этого выполняется усечение.

Кодировку достаточно указать только один раз, даже в случае применения нескольких функций.

22PunBB.Ru22-12-2015 23:29

Внимание

С версии PHP 5.3.0 эта функция считается УСТАРЕВШЕЙ. Крайне не рекомендуется полагаться на эту возможность.

Оставьте комментарий!

Комментарий будет опубликован после проверки. Вы соглашаетесь с правилами сайта.

(обязательно)

Навигация
  • Шаблоны для MaxSite CMS 22
  • jQuery и JavaScript 6
  • Java и Android 5
  • PHP/ООП 25
  • SQL 17
  • Albireo Framework 11
  • Berry CSS 7
  • CSS, HTML, LESS, SASS 23
  • PHP 37
  • Тайм-менеджмент 9
  • Софт 37
  • SEO 13
  • Git. GitHub 3
  • CodeIgniter 5
  • Landing Page 3
  • Alpine.js 14
  • Фильмы 2
  • Дневник 55

Вот здесь можно заказать создание сайта, шаблона или лендинга. Также вы можете выбрать готовые шаблоны для MaxSite CMS по небольшой цене. Также можно купить отдельные модули, компоненты для вашего сайта.

MaxSite.org
Как создать свой сайт

Услуги по созданию сайтов, блогов, лендингов
Обратная связь • Реклама на сайте
Карта сайта
Мои проекты
  • Шаблоны для вашего сайта
  • Заказать создание сайта
  • MaxSite CMS
  • Berry CSS (CSS Utilities)
  • Albireo Framework
  • UniCSS (Universal Atomic CSS)
  • Landing Page Framework
  • Бесплатные НТML-курсы
Ссылки
  • Telegram-канал
  • Github
  • Twitter
  • Telegram-бот
  • RSS
© MaxSite.org, 2006-2022. Работает на MaxSite CMS | Время: 0.3125 | SQL: 20 | Память: 4.66MB | Вход