Портрет 4X_Pro
Был в Сети 19 сент. 2025 г., 02:55
Мультиблог
4X_Pro
Кратко о себе: Web-разработчик. Пишу на PHP, Python, JavaScript. Знаю Ruby и Go, со студенческих времён более-менее помню C и asm. Специализируюсь на ускорении загрузки сайтов и разработке ботов для Telegram. Linuxоид (использую Debian+LXDE). Сторонник IndieWeb, slow lifer.

Социальные сети


Новости сайта в Telegram

t.me/4x_pro

Компьютерное

Выделение хештегов из текста

4X_Pro

С помощью уже упоминавшегося класса IntlBreakIterator можно легко выделить из текста хеш-теги. Для этого создадим итератор не по предложениям, а по словам с помощью: createWordInstance. Итерация с помощью IntlBreakIterator выдаёт смещения границ слов, что в данном случае не очень удобно. Поэтому воспользуемся методом IntlBreakIterator::getPartsIterator. Он создаёт ещё один итератор, который возвращает уже непосредственно сами слова. Далее, когда встретится символ # (он в режиме WordInstance считается отдельным словом), запоминаем этот факт и следующее слово обрабатываем как хеш-тег.

Вот пример кода:
function getHashTags($text) { $breaker =IntlBreakIterator::createWordInstance('ru_RU'); $breaker->setText($text); $iterator = $breaker->getPartsIterator(); $hashtags = array(); $mode = false; // теперь в $item будут сами слова, а не их смещения foreach ($iterator as $item) { // выставляем $mode в TRUE, если следующее слово нужно обработать как хеш-тег if ($item==='#') $mode=true; elseif ($mode && trim($item) && mb_strlen($item)>1) { // ряд дополнительных проверок, чтобы в хеш-теги не попадал мусор $hashtags[] = mb_strtolower($item); // обработка закочена, поэтому сбрасываем $mode до тех пор, пока не попадётся новый символ # $mode = false; } else $mode=false; } return $hashtags; }
Проверка mb_strlen($item)>1 нужна для отработки случаев вида #! #;,так как в этом случае знаки препинания рассматриваются как отдельные слова. Кроме того, хештеги из одной буквы обычно не имеют смысла.

Автоматическое создание анонса текста на PHP

4X_Pro

При создании скриптов для новостей или блогов часто требуется автоматически сформировать анонс из нескольких первых предложений полного текста, не превышающий определённой длины. Типичный подход для этих целей — это выделить с помощью mb_substr начальную часть текста нужной длины, а потом обрезать получившуюся часть до последней точки.

Но не все знают, что с версии 5.5 в PHP в модуле intl предусмотрен специальный класс IntlBreakIterator, который позволяет решать эту задачу более эффективно. У него есть несколько статических методов для создания итераторов, позволяющих выделять границы отдельных символов (createCharacterInstance), слов (createTitleInstance и createWordInstance, первый выделяет слова с включением пробелов и знаков препинания после них, второй — рассматривает пробелы и знаки препинания как отдельные слова) и целых предложений (createSentenceInstance). Для нашей задачи потребуется последний.

Далее всё просто: создаём экземпляр этого класса, передаём ему текст и получаем смещение конца ближайшего предложения с помощью методов preceding (ближайшая граница до нужной длины) и following (ближайшая граница после):
$test = 'Это тестовый текст. Текст длинный! И с многоточиями… Но нужно лишь только несколько начальных предложений. '; // задаём длину анонса $max_length = 80; // создаём экземпляр класса и указываем локаль для русского языка $breaker =IntlBreakIterator::createSentenceInstance('ru_RU'); // задаём текст для обработки $breaker->setText($test); // получаем ближайшую границу предложения перед указанной в $max_length позицией $offset = $breaker->preceding($max_length); // если оказалось, что первое предложение больше требуемой длины, берём его целиком, иначе анонс будет пустым if ($offset==0) $breaker->following($max_length); // выделяем начало текста $summary = substr($test,0,$offset); // выводим то, что получилось print $summary;
Важно: IntlBreakIterator возвращает смещения в байтах, поэтому для выделения строки нужно использовать substr, а не mb_substr!


Задать вопрос