2015-06-08 4 views
0

Я создаю функцию типа BBcode, которая вынимает весь код html из ввода формы, а затем преобразует [b] [/ b] в жирные теги, [u] в фактические теги u и [i] до фактического i.Автоматическое закрытие тегов в форме ввода?

Что касается меня, однако, если кто-либо, кто пишет и подает входные данные, не закрывает все теги. Я не хочу, чтобы это испортило всю страницу, когда информация будет отображаться позже.

Как бы вы порекомендовали мне автоматически закрыть все теги (только b, i и u разрешены) с помощью функции? Есть ли способ подсчитать, сколько [b] и сколько [/ b] есть, и если есть разница, добавьте, что многие [/ b] до конца? Или есть более простой способ?

BTW, я еще ничего не пробовал, потому что единственное, что я могу придумать, - подсчитать, сколько [b] есть, подсчитать, сколько [/ b] есть, получить разницу между ними и сделать цикл, который много раз добавляет закрывающий тег. Но я не знаю, как сделать первую часть этого (возвращая количество [b]).

Если кто-то хочет просветить меня о том, как это сделать (я знаю, что я знаю) Я пойду прямо, пытаясь понять это и дам вам знать, как это происходит. :)

+2

Что вы пытались до сих пор? Как вы уже сказали, вы уже думали о подсчете тегов. SO не предназначен для выполнения вашей работы, покажите нам, что вы пробовали, и мы поможем вам улучшить ваше решение. – Paul

+0

О, извините, позвольте мне уточнить. Я ничего не пробовал, потому что не знаю, как это сделать! – thinkofacard

ответ

0

Существуют разные возможности.

  • Вы можете сканировать содержимое с различными библиотеками, такими как «HTMLTidy», который будет удалить любые незакрытые теги

  • Также вы можете рассчитывать все теги и если они не закрыты и просто присоединять закрывающий тег для каждый незакрытый тег для контента динамически. preg_match может помочь вам здесь ...

  • Еще одна идея состоит в том, чтобы изолировать часть с написанным пользователем контентом в iframe, что может привести к тому, что сломанный HTML не повлияет на какие-либо элементы за пределами страницы.

+0

Предложение 1 непригодно, если сохранены bb-коды. Предложение 2 лучше, но они не будут закрыты в нужном месте. Предложение 3 просто плохо для многих причин, которые, я уверен, вы знаете. Возможно, четвертое предложение состояло бы в том, чтобы просто подсчитать открытые теги против закрытых тегов и просто предоставить ошибку, чтобы пользователь мог ее исправить? – Onimusha

+0

@Steini, если вы считаете только теги ожидания, вы не можете закрыть их в правильном порядке ... – Armage

+0

@up: Мое решение было всего лишь предложением схемы. Конечно, вы должны знать, какие теги bb-кода доступны и получить их все путем preg_match, и, следовательно, stpre их в правильном порядке. – Steini

1

Используйте простой массив. Вы добавляете каждый разрешенный открывающий тег, а затем «array_pop» каждого закрывающего тега. В конце обработки входного текста, если массив не пуст, вы можете закрыть теги ожидания.

И пожалуйста, покажите нам, что вы пытаетесь найти решение, прежде чем спрашивать, показать нам свой код :)

EDIT:

Ok, вот проект (не полированный один). Я использую FILO (первый в, последний выход) для хранения тегов.

Первый «цикл цикла» анализирует текст для хранения закрытых тегов. Второй цикл (foreach) добавляет метки ожидания в конец входного текста.

Если обнаружена ошибка, код возвращает ложь, он должен возвращать больше информации об ошибке :)

$text = "[u]hop[u]text[b]bar[/b][/u][b][i]foo"; 

echo closeTags($text); 

function closeTags($text) { 
    $tags = array(); 
    $currentTag = ''; 
    $tagOn = false; 
    $closingTagOn = false; 
    $lastPos = 2; 

    $len = strlen($text); 
    for ($i=0 ; $i < $len ; $i++) { 
     // reading tag ? 
     if ($tagOn or (!$tagOn and '[' === $text[$i])) { 
      $currentTag .= $text[$i]; 
      $tagOn = true; 
     } 

     // closing tag ? 
     if (isset($currentTag[1]) and '/' === $currentTag[1]) { 
      $closingTagOn = true; 
      $lastPos = 3; 
     } 

     // tag ending ? 
     if (isset($currentTag[$lastPos])) { 
      if (']' !== $currentTag[$lastPos]) { 
       return false; // malformed text 
      } 
      else { 
       if ($closingTagOn) { 
        // quick & dirty 
        if ($tags[count($tags)-1][1] === $currentTag[2]) { 
         array_pop($tags); 
        } 
        else { 
         // malformed, markups should not cross over each other 
         return false; 
        } 
       } 
       else { 
        // adding the tag 
        $tags[] = $currentTag; 
       } 

       // re-init 
       $currentTag = ''; 
       $tagOn = false; 
       $closingTagOn = false; 
       $lastPos = 2; 
      } 
     } 
    } 

    $tags = array_reverse($tags); 
    foreach($tags as $tag) { 
     $text .= '[/' . $tag[1] . ']'; 
    } 
    return $text; 
} 
+0

Хотя ОП заслуживает нисходящего за то, что не показал свою работу, просьба указать образец вашего предложения, если он обновит свой вопрос. Я бы попробовал это. Благодарю. Главное не знать, где закрыть теги (порядок и положение, но я думаю, что это будет ошибка пользователя) – Onimusha

+0

@Onimusha, ^^ это сделка «покажите мне свой код, я покажу вам свое». Итак, да, сейчас нет кода. И для вопроса «где» это вопрос просмотра веб-страницы, а не исправления входного текста: /, поэтому просто положите теги ожидания в конец. – Armage

0

Хорошо, я обнаружил, что PHP имеет изящный небольшой «аккуратный» класс, установленный в PHP5 +! Итак, это функция, с которой я пришел, и, похоже, она работает!

function bbcode($data) { 

    $patterns = array(); 
    $patterns[0] = '/</'; 
    $patterns[1] = '/>/'; 
    $new = preg_replace($patterns, "", $data); 

    $newer = sanitize($new); 

    $search = array('[b]', '[/b]', '[i]', '[/i]', '[u]', '[/u]'); 
    $replace = array('<b>', '</b>', '<i>', '</i>', '<u>', '</u>'); 

    $newest = str_replace($search, $replace, $newer); 

    $data1 = nl2br($newest); 

    $tidy = tidy_parse_string($data1); 
    $tidy->cleanRepair(); 
    return $tidy; 
} 
+0

Я должен указать, что функция sanitize() - это моя собственная функция, которая просто делает ее безопасной, обрезает и т. Д. Это не что-то особенное. – thinkofacard

+0

Вы также должны указать, что это не делает то, что было в вашем исходном вопросе ... Я смутился, когда его добавление закрывающих тегов автоматически? – Pogrindis

+0

Это то, что $ tidy-> cleanRepair(); функция. Попробуйте сами, или прочитайте об этом в руководстве php.net http://php.net/manual/en/tidy.cleanrepair.php – thinkofacard