У меня есть простое текстовое поле, где пользователи могут вводить описание своего продукта в моей фиктивной системе. Я разрешаю только теги <b><u> и <i> без каких-либо атрибутов, используя следующий код:
$description = strip_tags($_POST['description'], "<b><u><i>");
$description = preg_replace("/<([a-z][a-z0-9]*)[^>]*?(/?)>/i",'<$1$2>', $description);
Моя проблема в том, что тег остается без закрывающей части, например:
<b>This is a <i>Test
Теги <b> и <i> будут применяться ко всему, что идет после этой части. Есть ли надежный способ автоматически закрывать теги?
Я хочу, чтобы тег закрывался в конце пользовательского ввода, но только если он был оставлен открытым.
Покажите входящий нить.
@nullability Отредактировал вопрос с желаемым поведением. Я хочу, чтобы он был закрыт сразу после завершения ввода пользователем, но только если он оставил его незакрытым.
Кроме того, ваше регулярное выражение выглядит немного странно. Что ты пытался сделать?
@EugeneR Я получил регулярное выражение отсюда stackoverflow.com/questions/3026096/…






Этот код потребует дополнительной настройки, но он поможет вам понять суть идеи.
$tags = ['b', 'i', 'u'];
foreach($tags as $t){
if ($a = substr_count($message, "<$t>") != $b = substr_count($message, "</$t>"){
if ($a > $b){
$message .= str_repeat("<$t>", $a - $b);
} else {
// more closing tags then opening.
$message = strrev($message);
str_replace("<$t/>", '', $message, $b - $a);
$message = strrev($message);
}
}
}
$message содержит весь текст текстовой области. Он считает все теги и в случае несоответствия добавляется в конец строки.
В итоге я решил проблему с помощью Tidy. Вот код:
$tidy = new Tidy();
$description = $tidy->repairString($description, array(
'output-xml' => true,
'input-xml' => true,
'vertical-space' => false
));
Как узнать, где автоматически закрыть тег? Какое именно желаемое поведение?