Автоматическое создание анонса текста на PHP
Добавлено: 22 июн 2025, 19:29
https://4xpro.ru/profblog/text-summary/
PHP в модуле intl предусмотрен специальный класс IntlBreakIterator, который позволяет решать эту задачу более эффективно. У него есть несколько статических методов для создания итераторов, позволяющих выделять границы отдельных символов (createCharacterInstance), слов (createTitleInstance и createWordInstance, первый выделяет слова с включением пробелов и знаков препинания после них, второй — рассматривает пробелы и знаки препинания как отдельные слова) и целых предложений (createSentenceInstance). Для нашей задачи потребуется последний.
Далее всё просто: создаём экземпляр этого класса, передаём ему текст и получаем смещение конца ближайшего предложения с помощью методов preceding (ближайшая граница до нужной длины) и following (ближайшая граница после):
Важно: IntlBreakIterator возвращает смещения в байтах, поэтому для выделения строки нужно использовать substr, а не mb_substr!
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;