function smart_cut($text, $words = 3, $separator = ' ')Принимает три параметра, обязательный только первый:
{
$current_pos = 0;
for($i = 0; $i < $words; $i++)
{
$current_pos = strpos($text, $separator, ($current_pos + 1));
}
return substr($text, 0, $current_pos);
}
- Текст, над которым будет производиться манипуляция;
- Количество слов, после которого строка будет обрезана;
- Разделитель слов в исходном тексте.
Решение, которое было найдено, навскидку показалось не очень быстрым, поэтому я решил сделать свое. Вот такое решение предлагает Максим:
function maxsite_str_word($text, $counttext = 10, $sep = ' ') {Если описать суть решения maxsite_str_word, то звучит она так: создать массив, элементами которого являются все слова, переданные в качестве первого параметра, потом отобрать n первых элементов, соединить их в строку и вернуть ее. Очевидно, что если переданный текст будет достаточно большой, то такое решение будет работать медленно.
$words = split($sep, $text);
if ( count($words) < $counttext )
$text = join($sep, array_slice($words, 0, $counttext));
return $text;
}
Чтобы подтвердить свое предположение я провел ряд тестов (порядка 400) на сравнение быстродействия. Условия проведения были одинаковы: два идентичных php-файла, отличающихся только функцией обрезки строк, в одной директории на одном сервере. Каждый тест проводился по пять раз. В качестве параметров для теста использовался различный объем обрабатываемого текста и количество слов, до которого он должен быть обрезан.
Результаты можно посмотреть в таблице. По сводному графику видно, что при увеличении объема обрабатываемого текста время выполнения функции maxsite_str_word значительно увеличивается, а в решении smart_cut время выполнения на протяжении практически всего теста остается на одной отметке.
К тому же в реализации maxsite_str_word используется функция split, которая устарела в PHP версии новее 5.3.0.
Так будет красивее:
ОтветитьУдалитьfunction smart_cut($text, $words = 3) {
$match = array();
$r = preg_match("/^[^\s]+([\s]+[^\s]+){0,".($words-1)."}/", $text, $match);
if ($r)
return $match[0];
return '';
}
Этот комментарий был удален автором.
УдалитьМогу предположить, что из-за отсутствия циклов такое решение будет работать быстрее, однако мне всегда сложно было назвать регулярные выражения красивым решением. Может быть из-за неопытности.
ОтветитьУдалитьзачем регэкспы? только для красоты? а производительность то что упадет в 500 раз, это норм, да?
ОтветитьУдалить>>if ( count($words) < $counttext )
ОтветитьУдалитьдолжен быть другой знак:
if ( count($words) > $counttext )
в первой функции не учитывается, что в строке может быть меньше слов
ОтветитьУдалить