Модераторы: Aliance, skyboy, MoLeX, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как обрезать строку с форматированием 
:(
    Опции темы
SelenIT
Дата 28.4.2010, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 8
Всего: 401



Цитата(Gold Dragon @  28.4.2010,  07:29 Найти цитируемый пост)
что такое Tidy? 

Фактически готовый HTML-парсер.

Цитата(Gold Dragon @  28.4.2010,  08:15 Найти цитируемый пост)
не учтено всякие специальные символы типа «

У меня учтено;)
Цитата

'/((<[^<>]*>)*(\s+|(&#?\w+;)|[^<>\s])){0,'.$limit.'}/su'



--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
SickFxck
Дата 28.4.2010, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 16.4.2010

Репутация: 1
Всего: 1



Код

function htmlSubstr($html, $length)
{
    $out = '';
    $arr = preg_split('/(<.+?>|&#?\\w+;)/s', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
    $tagStack = array();

    for($i = 0, $l = 0; $i < count($arr); $i++) {
        if( $i & 1 ) {
            if( substr($arr[$i], 0, 2) == '</' ) {
                array_pop($tagStack);
            } elseif( $arr[$i][0] != '&' && substr($arr[$i], -2) != '/>' ) {
                array_push($tagStack, $arr[$i]);
            }

            if( $arr[$i][0] == '&' )
                $l++;

            $out .= $arr[$i];
        } else {
            if( ($l += strlen($arr[$i])) >= $length ) {
                $out .= substr($arr[$i], 0, $l - $length);
                break;
            } else {
                $out .= $arr[$i];
            }
        }
    }

    while( ($tag = array_pop($tagStack)) !== NULL ) {
        $out .= '</' . substr($tag, 1);
    }

    return $out;
}

PM MAIL   Вверх
SickFxck
Дата 28.4.2010, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 16.4.2010

Репутация: 1
Всего: 1



Цитата(Gold Dragon @  28.4.2010,  08:58 Найти цитируемый пост)
SickFxck, прокомментируй код.. Хочу разобраться 

Если кратко, то, встречая открывающий тег (парный), мы его пихаем в стек, если встретился закрывающий — выталкиваем. Если длина строки превысила допустимое количество — прерываем цикл. После выталкиваем все незакрытые теги.

Я пользуюсь тем, что preg_split($pattern, $subject, -1, PREG_SPLIT_DELIM_CAPTURE) возвращает массив в виде чередующихся строк и подстрок, подходящих под шаблон. То есть, тег всегда будет в нечётных индексах массива, а простой текст — в чётных.

Да и ещё один фикс:
Код

    while( ($tag = array_pop($tagStack)) !== NULL ) {
        $out .= '</' . strtok(substr($tag, 1), " \t>") . '>';
    }


P.S. И заметь, что, например, "&amp;" я считаю одним символом ("&"), а не 5-ю.

Это сообщение отредактировал(а) SickFxck - 28.4.2010, 17:59
PM MAIL   Вверх
Gold Dragon
Дата 29.4.2010, 07:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



боюсь что Tidy не могу использовать. не на всех серверах он установлен. Проверил у своих хостеров, только у одного стоит :(


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Gold Dragon
Дата 29.4.2010, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



никак не пойму почему количество заданных символов не соответствует реальной обрезке :(
и разница колеблется в случайном порядке, как в большую сторону так и в меньшую


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
SickFxck
Дата 29.4.2010, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 16.4.2010

Репутация: 1
Всего: 1



Цитата(Gold Dragon @  29.4.2010,  10:37 Найти цитируемый пост)
никак не пойму почему количество заданных символов не соответствует реальной обрезке

Ты про чей вариант?

Свой я уже пояснил:
Цитата(SickFxck @  28.4.2010,  14:40 Найти цитируемый пост)
P.S. И заметь, что, например, "&amp;" я считаю одним символом ("&"), а не 5-ю.

Поэтому нельзя делать проверку с помощью strlen().

Ах да. Действительно есть кое-что. Окончательный вариант:
Код

function htmlSubstr($html, $length)
{
    $out = '';
    $arr = preg_split('/(<.+?>|&#?\\w+;)/s', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
    $tagStack = array();

    for($i = 0, $l = 0; $i < count($arr); $i++) {
        if( $i & 1 ) {
            if( substr($arr[$i], 0, 2) == '</' ) {
                array_pop($tagStack);
            } elseif( $arr[$i][0] == '&' ) {
                $l++;
            } elseif( substr($arr[$i], -2) != '/>' ) {
                array_push($tagStack, $arr[$i]);
            }

            $out .= $arr[$i];
        } else {
            if( ($l += strlen($arr[$i])) >= $length ) {
                $out .= substr($arr[$i], 0, $length - $l + strlen($arr[$i]));
                break;
            } else {
                $out .= $arr[$i];
            }
        }
    }

    while( ($tag = array_pop($tagStack)) !== NULL ) {
        $out .= '</' . strtok(substr($tag, 1), " \t>") . '>';
    }

    return $out;
}


Код

function htmlStrlen($html)
{
    return strlen(preg_replace('/&#?\\w+;/', '?', strip_tags($html)));
}

assert(htmlStrlen(htmlSubstr('HTML-<strong>string</strong>', 6)) == 6);
assert(htmlStrlen(htmlSubstr('&amp;&#xD7;&amp;', 2)) == 2);
assert(htmlStrlen(htmlSubstr('<p class="p1">test &amp; test </p>', 5)) == 5);


Это сообщение отредактировал(а) SickFxck - 29.4.2010, 11:51
PM MAIL   Вверх
Gold Dragon
Дата 29.4.2010, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



теперь код отлично работает на этом этапе smile Но это при условии что код валидный

если есть <img...> а не <img ... /> то появится </img> smile

а можно как то включить в условия чтобы если встретится например тег <myqqq> то просто его игнорировать и оставить в коде?


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
SickFxck
Дата 29.4.2010, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 16.4.2010

Репутация: 1
Всего: 1



Делай массив таких тегов
Код

$single = array('img', ...);


Добавь условие здесь:
Код
} elseif( substr($arr[$i], -2) != '/>' ) {

substr(), strtok(), strtolower(), in_array()...

Это сообщение отредактировал(а) SickFxck - 29.4.2010, 11:59
PM MAIL   Вверх
SelenIT
Дата 29.4.2010, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 8
Всего: 401



Цитата(Gold Dragon @  29.4.2010,  07:39 Найти цитируемый пост)
Проверил у своих хостеров, только у одного стоит :( 

Я думаю, адекватного хостера можно попросить его добавить. Всё-таки стандартные решения надежнее, имхо (хотя бы тем, что не надо самому заводить массивы пустых тегов и разрешенных тегов)...


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
Gold Dragon
Дата 29.4.2010, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



SelenIT, согласен с тобой.. Но не всё так просто ... ни каждый хостер будет доставлять библиотеки по желанию пользователей...

хотя я думаю нужно и этот вариант сделать, а в настройках давать пользователю вариант выбирать... 


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Страницы: (3) Все 1 2 [3] 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Тексты | Следующая тема »


 




[ Время генерации скрипта: 0.0808 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.