Многие сталкивались с тем, что пользователи пишут что-то типа этого:
аааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааа
и в итоге страница расширяется, и становится не красиво. Ну первым делом многие пытаются скрыть это с помощью CSS(word-wrap или overflow: hidden). Но word-wrap работает не во всех браузерах, а overflow: hidden просто тупо скроет текст, что как бы меня тоже не устраивает.
Есть выход из этого! Вот функция, которая автоматически добавляет пробел или знак переноса (выбирать вам) в длинное слово.
[php:1:f1d9379887]<?php
function obrezka($str, $width, $break="\r\n") // строка, максимальная длина одного слова, разделитель
{
if(empty($str) || mb_strlen($str, "UTF-8") <= $width) // если строка пустая или меньше либо равна максимальной длине слова
return $str; // то возвращаем её, не обрабатывая
$break_width = mb_strlen($break, "UTF-8"); // длина разделителя
$str_width = mb_strlen($str, "UTF-8"); // длина строки
$return = ''; // переменная в которой будем записывать результат обработки
$last_space = false; // переменная в которой будут находится точки разрыва
for($i=0, $count=0; $i < $str_width; $i++, $count++)
{
if (mb_substr($str, $i, $break_width, "UTF-8") == $break)
{
$count = 0;
$return .= mb_substr($str, $i, $break_width, "UTF-8");
$i += $break_width - 1;
continue;
}
if(mb_substr($str, $i, 1, "UTF-8") == " ") // если находим пробел(точку разрыва), то запомним позицию
$last_space = $i;
if ($count > $width) // если считываемое слово уже превосходит нужную нам ширину
{
if(!$last_space) // если не встречали пробелов, то вставляем символ разделения
{
$return .= $break;
$count = 0;
}
else // иначе, если пробелы встречались
{
$drop = $i - $last_space; // ищем когда был пробел
if($drop > 0)
{
$return = mb_substr($return, 0, -$drop);
}
$return .= $break; // вставляем разделитель
$i = $last_space + ($break_width - 1); // обновляем указатели
$last_space = false; // обнуляем позицию пробела
$count = 0; // обнуляем счётчик кол-ва символов в слове
}
}
$return .= mb_substr($str, $i, 1, "UTF-8"); // добавляем символ
}
return $return; // результат
}
?>[/php:1:f1d9379887]
Пример работы этой функции.
[php:1:f1d9379887]<?php
$str="ахахахахахахааххаах";
echo obrezka($str, 5); // нужно нам, чтоб слова были короче шести символов
?>[/php:1:f1d9379887]
результат:
ахахах
ахахах
ааххаа
х
Пример работы с разделителем:
[php:1:f1d9379887]<?php
$str="ахахахахахахааххаах";
echo obrezka($str, 5, " "); // нужно нам, чтоб наши слова разделял пробел
?>[/php:1:f1d9379887]
Результат:
ахахах ахахах ааххаа х
Добавлю ещё пример для наглядности:
[php:1:f1d9379887]<?php
$str="xoxo ахахахахахахааххаах xox xox";
echo obrezka($str, 5, " "); // нужно нам, чтоб наши слова разделял пробел
?>[/php:1:f1d9379887]
Результат:
xoxo ахахах ахахах ааххаа х xox xox
Функция не трогает слова, которые короче указанной нами ширины
Не такая уж сложная функция, но полезная 
COOLBOY007, нет. wordwrap тупо вставляет перенос через определённое кол-во символов. А эта функция обрезает длинные слова, а не ставит перенос где попало.
13 Окт 2012, 11:40Виктор, ну нифига себе ты нагородил
Всё можно сделать куда проще.
Во-первых, использовать функцию wordwrap().
Во-вторых, если всё таки хочется написать свою функцию:
[php:1:8fd034dc0f]/**
* Нарезка длинных слов
*
* @param string $string исходная строка
* @param int $len максимальная длина слова (минимум 30)
* @param string $wrap разделитель
* @return string
*/
function wrap($string, $len = 30, $wrap = PHP_EOL) {
if($len < 30) $len = 30;
$string = preg_replace('~([^\s]{'.$len.'})~m', '$1'.$wrap, $string);
return $string;
}[/php:1:8fd034dc0f]
[php:1:c254c93e4f]<?php
$str='оооооооооооооооооооооооооооооооооооооооооооооооооооооооооочень длинное слово';
echo obrezka($str, 10, "<br />");
echo '<br />'.wordwrap($str, 10, "<br />", true);
?>[/php:1:c254c93e4f]
Результат:
ооооооооооо
ооооооооооо
ооооооооооо
ооооооооооо
ооооооооооо
ооочень длинное слово
ооооо
ооооо
ооооо
ооооо
ооооо
ооооо
ооооо
ооооо
ооооо
ооооо
ооооо
оооче
нь
длинн
ое
слово
wordwrap плохо работает с UTF-8 - первый недостаток
Попробуем латиницу
[php:1:c254c93e4f]<?php
$str='ooooooooooooooooooooooooooooooooooooooooooochen dlinnoe slovo';
echo obrez($str, 10, "<br />");
echo '<br />'.wordwrap($str, 10, "<br />", true);
?>[/php:1:c254c93e4f]
Результат:
ooooooooooo
ooooooooooo
ooooooooooo
ooooooooooc
hen dlinnoe slovo
oooooooooo
oooooooooo
oooooooooo
oooooooooo
ooochen
dlinnoe
slovo
Второй недостаток - переносит, даже когда не надо переносить. Если у нас есть пробел, то перенос будет автоматически, но функция wordwrap так не думает.
Функция obrezka более универсальна
добавлено спустя 6 минут:
Okula, не дружу я с регуляркой
Мне она не нравится. Я когда первый раз увидел, что надо сделать, чтоб проверить E-Mail на валидность(тогда ещё небыло функции filter_var($mail, FILTER_VALIDATE_EMAIL), либо я её не знал), я испугался и закрыл браузер
Я даже проверку на содержание в строке только английских символов и чисел либо русских символов и чисел сам написал
[php:1:c254c93e4f]<?php
function valid($text, $p1=" qwertyuiopasdfghjklmnbvcxz1234567890", $p2=" йцукенгшщзхъфывапролджэячсмитьбюё1234567890")
{
$i=strlen1($text);
$text=mb_strtolower($text, 'utf-8');
$k=0;
while ($k<=($i-1))
{
if(mb_strpos($p1, $text[$k],0,"utf-8")==0)$o1=1;
$k++;
}
$k=0;
while ($k<=($i-1))
{
if(mb_strpos($p2, $text[$k],0, "utf-8")==0)$o2=1;
$k++;
}
if($o1==1 && $o2==1)
return false;
else
return true;
}
?>[/php:1:c254c93e4f]
Виктор, и что, что ты не дружишь. Это не делает твой код лучше, а даже наоборот - хуже.
Громоздить такие велосипеды - это уже не good.
Могу сказать только одно - учи регулярки, они простые.
Okula, чем хуже?)
Тем что работать дольше будет?)
добавлено спустя 2 минуты:
Okula, я кстати находил пример с регуляркой. Но чёт не доверяю я им даже 
Виктор, во-первых твой велосипед работает дольше.
Во-вторых большой объём кода делает скрипт менее читабильным и понятным.
Ну и в третьих - всё это можно реализовать более элегантно, что уменьшит скрипт по весу и сделает его понятным для других пользователей.
Не доверяешь регуляркам - это потому что не знаешь как они работают. Если бы ты знал что значит каждый шаблон и масска ты бы так не говорил.
Я сейчас пишу регулярки подчти не заглядывая в var_dump() для того чтобы узнать что получилось (это что касается простых и не очень регуллярок).
Со сложными приходится немного попатеть, но они встречаются редко (только для каких-то экзатических случаев).