За последние 24 часа нас посетили 23784 программиста и 1610 роботов. Сейчас ищут 933 программиста ...

Разбить вывод текста . Регулярка и что еще ??

Тема в разделе "PHP для новичков", создана пользователем Dima4321, 1 фев 2011.

  1. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    Еще раз привет.


    Суть проблемы такова. Иногда ячейки (пункты, описания) которые выводятся из базы имеют большой вес и не хочется все это добро вешать на одну страницу уж слишком она становится тяжелой и длинной. Поэтому хочу разбить такую страничку в зависмотсти от условия на 2,3. или 4.

    Вопрос к чему можно подвязаться с точки зрения условия . Длина строки в символах ?? кол-во строк ??

    Как правильно записать это условие ?? естественно html должен быть валидным. Т.е. если обрыв..то обрыв после очередного </p> или </table> или </div> и т.п. Чтобы все было гораманично и фразы таблицы или блоки имели окончание.

    Предполагаю, что еще нужна будет регулярка.

    Как приблизительно соединить воедино.

    Напомню контент берется из MYSQL конкретной ячейки.

    Видел недавно подобный вопрос у кого-то. Но видел ответой на него..а потом и вовсе потерял тему или ее удалили..
     
  2. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    Господа, шооо такое ?? смотрю отвечает на форуме 2-3 человека. У всех остальных спячка зимняя или не сезон ??))

    Прием как слышно !! )
     
  3. Gromo

    Gromo Активный пользователь

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Dima4321
    теги всегда должны быть закрыты. так что регулярка не подходит, если в тексте есть вложенные теги.
     
  4. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    Gromo
    Да почему же не подойдет ? Подойдет . Я имел ввиду контент такого типа.

    На страницу выводится 10 таблиц из одной ячейки mysql допутим это треклисты альбомов.

    т.е
    3 альбома на одну страницу
    3 альбома на вторую страницу
    3 альбома на третью страницу
    1 альбом на четвертую страницу

    как такое реализовать писать длинную регулярку с проверкой на if или есть проще методы..??

    Или все таки регулярка не подходит ?)))


    Отмечу , что изначально это целиковый контент перед занесением в базу. т.е 10 таблиц на одном листе.
     
  5. Gromo

    Gromo Активный пользователь

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Dima4321
    я думаю, что такой подход сам по себе неправильный
     
  6. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    Вот приблизительный детский подход

    PHP:
    1. <?php
    2. ini_set('display_errors',1);
    3.  
    4. $n='<p>Hello my friend</p><p>goodbuy</p>';
    5.  
    6. preg_match_all('|<p>.+?</p>|si',$n,$matches);
    7.  
    8.  
    9. if(isset($matches[0][1]))
    10.  
    11. {
    12. echo $matches[0][0];
    13. echo '<a href="page.php">1</a>'; // вот здесь как-то надо передать массив
    14. $_SESSION['name'] = "{$matches[0][1]}";
    15. }
    16. else
    17. {
    18.  echo $matches[0][0];
    19. }
    20.  
    21.  
    22.  
    23. ?>
    PHP:
    1. <?php
    2. ini_set('display_errors',1);
    3.  
    4. echo "other page";
    5. print_r($_SESSION['name']);
    6.  
    7.  
    8. ?>
    Неужели никто подобным не знаимается..?? И все лепят войну и мир на одну страницу ??))
     
  7. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    нет. все заполняют данные о КАЖДОМ альбоме (или одной главе Войны и мира) в отдельную строку БД, а потом используют обычный постраничный вывод
     
  8. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    Хорошо а как тогда поступить если ко мне уже пришел контент в виде переменной по объему равный войне и мир. Я же должен его сам разбить и вставить в базу.)) как ?? !!

    простым explode тут уже не обойтись ! ))
     
  9. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Мы лепим. =)) С указанием книжных страниц, структурой, навигацией по страницам и сносками.
    Правда "Войну и Мир" мы не оцифровывали... у нас направленность другая.
     
  10. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Твоими любимыми регулярками)

    Ну ты же знаешь что именно парсишь, знаешь структуру контента. Наверняка можно выделить определенные блоки.
    Если речь идет например о муз. группах - думаю структура будет достаточно строгой.

    Загоняй отдельные блоки в отдельные ячейки
     
  11. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    tommyangelo я думаю ты прав. ))

    минус моего приема с сессиями ---- страницы не проиндексируются если не пойдут с 1 страницы.

    +

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


    Имею контент. он состоит только из <h1 2 3>) и тегов <p> после моего парсинга.

    Теперь хочу разделить эту страницу как минимум на 2. Весь контент пока в $new3


    PHP:
    1. preg_match('#(.+?<h[234]>.+?</h[234]>.+?<h[234]>.+?</h[234]>.+?<h[234]>.+?</h[234]>.+?)(<h[234]>.+)#si',$new3,$match);
    2.  if(isset($match[1]))
    3.  {
    4.  echo $match[1];
    5.  echo "2page <br>";
    6.  echo $match[2];
    7.  }
    8.  else
    9.  {
    10.  echo $new3;
    11.  
    12.  }
    13.  }
    Короче по факту теперь вместо одной переменной $new3 , я имею как правило 2. ($match[1] $match[2])

    Их я и должен привязать к определенному имени и id.

    Как это было сделать с одной перменной -понятно.
    А как сделать связку на 2 переменные . ставить еще одни столбик в mysql ???
    Можно пример или мысль ??
    Пожалуйста сжальтесь над честным человеком ))) ???
    может пару строк скрипта мм..??)
     
  12. Gromo

    Gromo Активный пользователь

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Dima4321
    код тут не проблема. проблема - разделить текст на две, примерно равные части.
    как бы ты разделял код вручную?
     
  13. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0

    Gromo

    разделил бы по ровну на 2 части . ну и чтобы логика сохранялась.

    Затем бы ту часть котрую я перенес (вырезал из 1 страницы) вставил в шаблон типа такого

    <html>
    <body>
    $conent

    </body>
    </html>


    У меня теперь делема как хранить в mySql вторую страницу.)) и как ее выводить ))
     
  14. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    Вот вкратце вывод моего контента:

    PHP:
    PHP:
    1. $page = $_GET['band'];// получил переменную по ссылке методом get
    2.  
    3. $sql = "SELECT * FROM groups WHERE NAME = '$page'";
    4.  
    5.  
    6.    $data = mysql_query($sql);
    7.    $row = mysql_fetch_assoc($data);
    8.  
    9.  echo $row['ABOUT'];// хочу вывести контент , но он большой и хочу кго разделить как минимум на 2 части (2 страницы)
    как правильно вывести данные ?? или даже так как лучше их положить в базу , чтобы потом вывести. При получении $_GET['band'].

    подрузамеватется оптимальный вариант чтобы не нагружать базу и т.п.
     
  15. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    есть вот такая мысль. Скажите это нормальный прием или нет. Решил добавить 2 столбик для MYSQL ---- ABOUT2


    page.php?band=$page
    PHP:
    1. <?php
    2. ini_set('display_errors',1);
    3.  
    4.  
    5. $page = $_GET['band'];// получил переменную по ссылке методом get
    6.  
    7. $sql = "SELECT * FROM groups WHERE NAME = '$page'";
    8.  
    9.  
    10.    $data = mysql_query($sql);
    11.    $row = mysql_fetch_assoc($data);
    12.  
    13.  echo $row['ABOUT'];
    14.  if(!empty($row['ABOUT2']))
    15.  {
    16.  <a href="page2.php?band=$page">page 2</a>
    17.  }
    18.  
    19. ?>

    page2.php?band=$page

    PHP:
    1. <?
    2. $page = $_GET['band'];
    3. $sql = "SELECT * FROM groups WHERE NAME = '$page'";
    4.  
    5.    $data = mysql_query($sql);
    6.    $row = mysql_fetch_assoc($data);
    7.    echo $row['ABOUT2'];
    8.  
    9.  <a href="page.php?band=$page">page1</a>
    10.  
    11.  ?>
     
  16. Gromo

    Gromo Активный пользователь

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    по факту, как человек бы разделил:
    просматриваем текст, записываем открывающие теги.
    если встречается закрывающий тег - вычёркиваем тег, который его открывал.

    доходим до какого-либо лимита количества текста, смотрим:
    если остались открывающие теги - нужно их все закрыть,
    а к следующему куску текста - открыть.

    это реализуется с помощью понятия стека.

    Для наглядности, возьмём текст:

    HTML:
    1. <div class="text">
    2.  <p>
    3.   <h1>заголовок</h1>
    4.   текст 1
    5.  </p>
    6.  <p>
    7.   текст 1 - продолжение.
    8.   ----------------------------------
    9.   текст 2 - на другой странице
    10.  </p>
    11. </div>
    нужно разделить по черте ---------------
    для этого нужно будет вместо черты закрыть все теги, которые были открыты,
    а на следующей странице все эти теги открыть заново. т.е. получится:

    HTML:
    1. <div class="text">
    2.  <p>
    3.   <h1>заголовок</h1>
    4.   текст 1
    5.  </p>
    6.  <p>
    7.   текст 1 - продолжение.
    8.   </p></div>
    9.   ----------------------------------
    10. <div class="text">
    11.  <p>
    12.   текст 2 - на другой странице
    13.  </p>
    14. </div>
    а ещё было бы хорошо разделять не по количеству текста,
    а логически - когда предложение заканчивается,
    или, на крайний случай, заканчивается слово.


    а т.к. эти операции довольно дорогостоящие,
    то лучше разбивать текст только один раз - при загрузке.

    примерно такого объяснения я от тебя ждал, а не пары слов
     
  17. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    Gromo огромное спасибо. что возишься со мной и еще с кучей таких же как я )
    твоя реализация досатточно трудоемка, ее сложно заточить под определенный изначальный контент. Поэтому для себя я решил пойти немного другим путем и обриcовал выше. Повторюсь

    1. Считаю, что снала надо оптимизировать тот контент кторый я получил под свои нужды для удобного вывода а также постраничной навигации.
    2. Поэтому применянется несколько функций к спрасенному а именно stritags, что-то остается естсествено )) preg_replace и str_replace.
    3. Затем финальная регулярка для самой разбивки
    в моем случае она иделаьно вписывается в рамки переработанного контента
    preg_match('#(.+?<h[234]>.+?</h[234]>.+?<h[234]>.+?</h[234]>.+?<h[234]>.+?</h[234]>.+?)(<h[234]>.+)#si',$new3,$match);

    $match[1] и $match[2] 2 мои страницы пускай они поделены и не совсем по ровну. Но они досатточно корректны с точки рения конца слов, предложений и закрыв. тегов.

    Думаю я придумаю сложное условие которое будет разбивать на 2-3-4 страницы в случае маленького контента будет оставаться 1 страница.

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

    Один из вариантов я выложил выше для критики, как раз перед твоим сообщением.
     
  18. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Если делать нормализацию, то логичней будет создать отдельную таблицу groups_about
    В ней будет 4 столбца

    id group_id page_id about

    Собственно запрос

    SELECT groups.*, ga.ABOUT FROM groups INNER JOIN groups_about AS ga ON groups.id = ga.group_id WHERE groups.id = ? AND ga.page_id = ?

    На месте знаков вопросов - твои значения id группы и номер страницы

    Плюсы такого подхода - неограниченное количество страниц по каждой группе, ABOUT всегда будет называться ABOUT а не ABOUT2, ABOUT3 и т.д.

    Минусов нет)))

    P.S. - id там у тебя или name - значения не имеет. просто я обычно с id работаю, так удобнее
     
  19. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    tommyangelo

    Честно убил своим запросом, перечитывал раз пять очень сложно понять )))


    Код (Text):
    1. SELECT groups.*, ga.ABOUT FROM groups INNER JOIN groups_about AS ga ON groups.id = ga.group_id WHERE groups.id = ? AND ga.page_id = ?
    шшшо такое ga. ?? и как понимать эту строку -- groups.*

    Дык я изначально не знаю сколько страниц должно выводиться . Как тогда я передам page id ??))

    Можно чуть подробней ??

    Уяснил стобики
    1. ID (наверно для связки с другой таблицей откда бать сам id)
    2. GROUP ID ( свой особенный номер)
    3. PAGE ID (номер 1 или 2 или 3 или 4 или 5)
    4. ABOUT (определенный контент напротив каждого page id)

    Итого Page ID и ABOUT всегда в связке в одном ряду.

    т.е. как мне видится в скрипте привы выводе контента первой страницы будут еще ссылки типа

    band.php?band=S_GET[GROUP ID]&number=$_GET[PAGE ID]

    Запутался что почитать на русском про такие сложные запросы и про архитектуру базы.??
     
  20. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    groups.* - это значит все поля из таблицы groups

    Ты ж пишешь - SELECT * - вот это и есть та самая звездочка. Только с уточнением из какой именно таблицы выбирать

    При помощи INNER JOIN подтягиваем данные из таблицы groups_about , причем INNER говорит о том, что подтянутся ТОЛЬКО ТЕ у которых есть совпадения по полю, указанному в параметре ON
    т.е. только те у которых значение group_id присутствует в id из groups

    Дальше 2 условия
    1) Оставляем только одну строку из groups по её id
    2) Оставляем только одну строку из groups_about по номеру страницы

    Да, совершенно верно. Передавать 2 параметра - имя(или id) группы и номер страницы

    Первая страница всегда page_id = 1

    Дальше - допустим выбрать все страницы чтобы показать пользователю их список - SELECT page_id FROM groups_about WHERE group_id = "наша группа"

    это просто алиас, чтобы каждый раз не писать имя таблицы groups_about я его сократил до ga )))

    Как мог объяснил))))

    Ну ты попробуй сначала создать в базе данных такую структуру, побаловаться с запросами. Без php-интерфейса. его потом напишешь.

    Почитать...хз... мне джоины раз показали, потом сам интуитивно учился))) Там ничего сложного, правда.
     
  21. Gromo

    Gromo Активный пользователь

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Я бы сделал запрос немного по другому.

    Две таблицы для ясности (как я их вижу):
    [sql]CREATE TABLE bands (
    `band_id` SERIAL,
    `name` VARCHAR(99)
    );

    CREATE TABLE band_info_pages (
    `band_id` INT UNSIGNED NOT NULL,
    `page` INT,
    `content` TEXT
    );[/sql]

    т.к. основной запрос идёт на текст, то я бы и выбирал его из таблицы band_info_pages

    [sql]SELECT `content`, `page`, `name` FROM band_info_pages
    LEFT JOIN bands USING(`band_id`)
    WHERE band_info_pages.band_id = '$band_id' and `page` = '$page';[/sql]

    т.е. content, page идут из таблицы band_info_pages, a name - из таблицы bands.

    Количество страниц подсчитывается запросом:
    [sql]SELECT count(*) as number_of_pages FROM band_info_pages WHERE band_id = '$band_id';[/sql]


    Думаю, что такие запросы выглядят проще, и понять их тоже будет проще ;)
     
  22. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Gromo
    Я исходил из того, что в таблице bands множество полей, не только название :)
     
  23. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    SERIAL
    Где можно почитать про это ??

    Я так понмаю к строке привязывается несколько строк ??
     
  24. Gromo

    Gromo Активный пользователь

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Dima4321
    SERIAL - INT UNSIGNED NOT NULL AUTO_INCREMENT