За последние 24 часа нас посетили 18719 программистов и 1641 робот. Сейчас ищут 1152 программиста ...

BBcode`s - Патерны (рег. выр.), функции, теория.

Тема в разделе "Решения, алгоритмы", создана пользователем Hight, 29 июн 2007.

  1. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Наверняка у многих из нас есть свои наработки по BBcode`ам. Фичи и ноу-хау, методики тестирования безопасности и т.д. Может быть поделимся наработками?! Сделаем небольшой сборничек регулярок и теории по BBcod`ам, а то меня нубы запарили, на str_replace`е BBcode`ы делают, а потом спрашивают почему дизайн весь кривой стал... :lol:

    Ладно, раз уж затеял тему, вот:
    PHP:
    1. <?php
    2. //$msg - текст сообщения в котором есть PHP-код, выделенный тегами [ php ][/ php ].
    3. // про htmlspecialchars беспокоится не стоит, возвращённая подмаска декодируется.
    4.  
    5. $msg = preg_replace_callback("#\[php\](.*?)\[/php\]#si",
    6. create_function('$matches', '
    7. $matches[1] = str_replace("&gt;", ">", $matches[1]);
    8. $matches[1] = str_replace("&lt;", "<", $matches[1]);
    9. $matches[1] = str_replace("&quot;", "\"", $matches[1]);
    10. $matches[1] = str_replace("&amp;", "&", $matches[1]);
    11. $matches[1] = highlight_string($matches[1], 1);
    12. $result = "<div class=\"bbcode_php\">".$matches[1]."</div>";
    13. return $result;'),
    14. $msg);
    15.  
    Всем тут знакомый BBcode подсветки синтаксиса PHP. Сам знаю, что странно реализовал, но работает вполне корректно.
    А вот и CSS к нему:
    [css]div.bbcode_php{
    background-color:#FFFFFF;
    border-width:1px;
    border-color:#999999;
    border-style:dashed;
    margin:5px;
    padding:5px;
    }[/css]
     
  2. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    PHP:
    1. <?php
    2. $text = htmlspecialchars($text);
    3. $text = preg_replace(
    4.             '/\[php\](.*)\[\/php\]/Usie',
    5.             "highlight_string(stripslashes(htmlspecialchars_decode('$1')), true)",
    6.             $text);
    7. ?>
     
  3. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Sergey89
    В php4 работать не будет. И как ты хочешь у себя html использовать для выделения?! Внешнюю функцию писать, очень удобно наверное :)


    Вот мой модернизированный вариант:
    PHP:
    1.  
    2. <?php
    3. /********* Подсветка синтаксиса [ php][/ php] *********/
    4. $msg = preg_replace_callback("#\[php\](.*?)\[/php\]#si",
    5. create_function('$matches', '
    6. $matches[1] = str_replace("&gt;", ">", $matches[1]);
    7. $matches[1] = str_replace("&lt;", "<", $matches[1]);
    8. $matches[1] = str_replace("&quot;", "\"", $matches[1]);
    9. $matches[1] = str_replace("&amp;", "&", $matches[1]);
    10. $matches[1] = (stripos($matches[1], "<?php") != (int)1)? "<?php ".$matches[1]."" : $matches[1];
    11. $matches[1] = highlight_string($matches[1], 1);
    12. $result = "<div class=\"bbcode_php\">".$matches[1]."</div>";
    13. return $result;'),
    14. $msg);
    15. /********* Подсветка синтаксиса [ php][/ php] *********/
    16.  
    теперь автоматом вставляется префикс в виде <?php в случае необходимости
     
  4. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Давно забыл про него :wink:

    Не понял тебя...

    Mod:
    PHP:
    1.  
    2. <?php
    3. $text = htmlspecialchars($text);
    4.  
    5. $text = preg_replace(
    6.             '/\[php\](.*)\[\/php\]/Usie',
    7.             "highlight_string(stripslashes(htmlspecialchars_decode(
    8.            (stripos('$1', '&lt;?php') === false ? '<?php $1?>' : '$1')
    9.            )), true)",
    10.             $text);
    11. ?>
     
  5. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    нафига нужны бибикоды, если есть хтмл? нафига нужен хтмл если есть визивиг? :D
     
  6. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Я представляю посетителя, который сам раскрашивает код :)
     
  7. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    В базе хранить HTML очень накладно на по объёму - поэтому и делают BBCode.
     
  8. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    Sergey89, <php>а тута пхп код</php>

    Psih, ага, при этом многие перед сохранением в базу переводят ббкоды в хтмл :)
     
  9. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Чтобы потом писать парсер HTML to BBCODE?
     
  10. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    показ сообщения происходит много чаще, чем показ формы его редактирования...
     
  11. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Sergey89
    dark-demon
    У нас написано HTML -> BBcode. При этом этот парсер в BBCode переводит только строго то, что можно: Вплоть до определённых CSS атрибутов и их значений - всё остальное вырезаеться strip_tags() и после чего сохраняеться в базу. А всё потому, что юзеры пишут в визивике, поэтому обрабатываем HTML и оставляем только то, что мы разрешаем и вырезаем всё остальное. И вполне пашет. Кстати этот парсер можно найти здесь на форуме - он выложен в топике "Авторам движков на PHP". Он же в последствии переводит BBCode в валидный HTML при выводе (и для редактирования в визивике)
     
  12. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Psih, а не легче сразу перевести в валидный HTML? Зачем нужна двойная работа?
    Если можно сразу
    Или я чего-то не допонял? :)
     
  13. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Хранить в базе [e10] намного лучше чем <img src="/images/smiles/smile.gif" alt=":D" title=":D" /> . К тому же у нас есть ещё и WAP версия сайта - там HTML не катит, надо выводить WML :)
    Вопросы? :)
     
  14. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    А ещё бывают RSS отсылка сообщений по мылу, экспорт в PDF, CSV, и.т.д.

    Всё что ввёл пользователь надо хранить так как оно пришло (я бы вообще в blob пихал, но это уже и в правду маразм)
     
  15. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Теперь вопросов нет. ;)
     
  16. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Всё, нормально работает и выглядит красиво:
    PHP:
    1. <?php
    2. /********* Подсветка синтаксиса [ php][ /php] *********/
    3. $msg = preg_replace_callback("#\[php\](.*?)\[/php\]#si",
    4. create_function('$matches', '
    5. $matches[1] = str_replace("&gt;", ">", $matches[1]);
    6. $matches[1] = str_replace("&lt;", "<", $matches[1]);
    7. $matches[1] = str_replace("&quot;", "\"", $matches[1]);
    8. $matches[1] = str_replace("&amp;", "&", $matches[1]);
    9. $matches[1] = (stripos($matches[1], "<?php") === false)? "<?php ".$matches[1]."" : $matches[1];
    10. $matches[1] = highlight_string($matches[1], 1);
    11. $result = "<div class=\"bbcode_php\"><b><u>PHP</u></b><br /><br />".$matches[1]."</div>";
    12. return $result;'),
    13. $msg);
    14. /********* Подсветка синтаксиса [ php][ /php] *********/
     
  17. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Моё круче (завтра будет ровно 3 года как я это писал)
    PHP:
    1. <?php
    2.     $text = substr($_POST["text"],0);
    3.     $text = htmlspecialchars(stripslashes($text));
    4.     $text = strtr($text,"[[i]b[/i]]", "<b>");
    5.     $text = strtr($text,"[/[i]b[/i]]", "</b>");
    6.     $text = strtr($text,"[[i]i[/i]]", "<i>");
    7.     $text = strtr($text,"[/[i]i[/i]]", "</i>");
    8.     $text = strtr($text,"[[i]u[/i]]", "<u>");
    9.     $text = strtr($text,"[/[i]u[/i]]", "</u>");
    10.     $text = nl2br($text);
    11. ?>
    А теперь внимание вопрос, о чём я думал, и какую траву курил ?
     
  18. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Vladson
    PHP:
    1. <?php
    2. /********* Тип шрифта *********/
    3.     $patterns[] = "#\[b\](.*?)\[/b\]#si"; $replacements[] = "<b>\${1}</b>";
    4.     $patterns[] = "#\[u\](.*?)\[/u\]#si"; $replacements[] = "<u>\${1}</u>";
    5.     $patterns[] = "#\[i\](.*?)\[/i\]#si"; $replacements[] = "<i>\${1}</i>";
    6.  
    7.     $msg = preg_replace($patterns, $replacements, $msg);
    8.  
    9.     unset($patterns); unset($replacements);
    10.     /********* Тип шрифта *********/
    ;)
     
  19. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Кстати юзать
    Код (Text):
    1. (.*?)
    надо окуратнее (многие его пихают куда не поподя а потом XSS на сайте плодятся как кролики)
     
  20. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Vladson
    Согласен. В моём случае с типом шрифта уязвимости нет, потому-что перед этим я делаю htmlspecialchars. А если мы хотим выделить ссылку, то там да, регулярку надо очень хорошо продумывать.
     
  21. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    Код (Text):
    1. Хранить в базе [e10] намного лучше чем <img src="/images/smiles/smile.gif" alt="Very Happy" title="Very Happy" /> .
    1. текстовые смайлики рулят ^_^
    2. не надо пихать в alt текст из title
    3. title для смайликов не имеет смысла, потому как пользователи вставляют смайлики ориентируясь на изображение. соответственно предустановленная семантика для смайликов редко когда является адэкватной. яркий пример - стандартный в пхпББ смайлик показывающий язык.
    4. <emo>^_^</emo> - такой вариант легко преобразовать во всё, что угодно, плюс можно выводить без преобразования - будет отображён обычный текстовый смайлик.
     
  22. Vitas

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

    С нами с:
    7 фев 2006
    Сообщения:
    595
    Симпатии:
    0
    Адрес:
    Новосибирск, Академгородок
    PHP:
    1.  
    2. [ php]
    3. <?php
    4.  
    5. echo "[ /php]";
    6.  
    7. ?>
    8. [ /php]
    9.  
    ?
     
  23. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    вообще говоря, конструкция
    Код (Text):
    1.   <?php
    2.  
    3.   echo "[/php]";
    4.  
    5.   ?>
    самодостаточна и ни в каких ббкодах не нуждается ;-)

    кстати, именно так и сделано на php.net...
     
  24. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    Vitas, кстати, да. имхо, наиболее правильным было бы выделение исходников в отдельную сущность - что-то типа pastebin, но с интеграцией в форум...
     
  25. C

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

    С нами с:
    28 май 2006
    Сообщения:
    326
    Симпатии:
    0
    (.*?) - а чё тут опасного и зачем там вопросительный знак.