Закрыть незакрытые тэги

Четверг, 30 апреля 2009

Функция позволяет закрыть незакрытые HTML-тэги.

function closetags($html) {
$single_tags = array('meta','img','br','link','area','input','hr','col','param','base');
preg_match_all('~<([a-z0-9]+)(?: .*)?(?<![/|/ ])>~iU', $html, $result);
$openedtags = $result[1];
preg_match_all('~</([a-z0-9]+)>~iU', $html, $result);
$closedtags = $result[1];
$len_opened = count($openedtags);
if (count($closedtags) == $len_opened) {
return $html;
}
$openedtags = array_reverse($openedtags);
for ($i=0; $i < $len_opened; $i++) {
if (!in_array($openedtags[$i], $single_tags)) {
if (FALSE !== ($key = array_search($openedtags[$i], $closedtags))) {
unset($closedtags[$key]);
}
else {
$html .= '</'.$openedtags[$i].'>';
}
}
}
return $html;
}



Автор не я. Кто написал не помню…

Тэги:

Комментарии

#1 Николай 30.04.09, 17:30

а насколько правильно он закрывает теги?

#2 Sam 30.04.09, 18:03

Николай
Попробуйте.

#3 SelenIT 30.04.09, 19:52

Имхо, баловство это. Для XML бы еще прокатило, но для HTML, с его неявным закрытием "пэшек" перед любым блочным тегом и т.п., это мало что меняет. Да и зачем так изворачиваться, когда есть Tidy?

Кстати, список одиночных тегов неполон -- как минимум, есть еще INPUT, HR, COL, PARAM и BASE...

#4 Sam 01.05.09, 12:27

SelenIT
Решение конечно же для закрытия XHTML. Использовано как раз было из-за отсутствия Tidy.
Список одиночных действительно неполон. Добавлю.

#5 Spider 03.05.09, 00:23

Спасибо, как нельзя кстати. Как раз собирался писать такую функцию

#6 Индеетс 19.05.09, 17:28

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


function closetags($text)
{
// Выбираем абсолютно все теги
if (preg_match_all("/<([/]?)([wd]+)[^>/]*>/", $text, $matches, PREG_SET_ORDER))
{
$stack = array();
foreach ($matches as $k => $match)
{
$tag = strtolower($match[2]);
if (!$match[1])
// если тег открывается добавляем в стек
$stack[] = $tag;
elseif (end($stack) == $tag)
// если тег закрывается, удаляем из стека
array_pop($stack);
else
// если это закрывающий тег, который не открыт, открываем
$text = '<'.$tag.'>'.$text;
}
while ($tag = array_pop($stack))
// закрываем все открытые теги
$text .= '</'.$tag.'>';
}
return $text;
}


Тоже не помню где подсмотрел

#7 Индеетс 19.05.09, 17:36

В регулярке некорректно обработаны обратные слэши, автору скрипта низачод)
Правильно:


if (preg_match_all("/<([СЛЭШ/]?)([СЛЭШwСЛЭШd]+)[^>СЛЭШ/]*>/", $text, $matches, PREG_SET_ORDER))

#8 Анатолий 30.05.09, 18:05

спасибо большое за скрипт!

#9 fartemon 05.06.09, 17:37

у меня возник вопрос, что если скрипт не в том порядке закроет теги, в случае дивной верски - он может наломать дров, кто его уже пробовал? напишите свои впечатления плиз

#10 SpYeR 01.11.09, 10:59

Я сделал, что если тег table есть, не обрезать, т.к. это зачастую вёрстку нехило сбивает.

#11 Guest 21.12.09, 21:52

Большое Спасибо за скрипты. Будем тестировать!!!

Оставить комментарий




Подписаться на RSS

Интересное

Разделы

  1. (5)
  2. (11)
  3. (6)
  4. (9)
  5. (6)
  6. (6)
  7. (16)
  8. (59)
  9. (264)
  10. (51)
  11. (16)
  12. (12)
  13. (37)
  14. (5)
  15. (10)
  16. (14)
  17. (18)
  18. (12)
  19. (6)
  20. (8)
  21. (7)
  22. (29)
  23. (62)
  24. (18)
  25. (64)
  26. (5)
  27. (193)
  28. (56)
  29. (6)
  30. (18)
  31. (72)
  32. (27)
  33. (65)
  34. (32)
  35. (10)
  36. (5)
  37. (6)
  38. (5)
  39. (309)
  40. (11)
  41. (6)
  42. (12)
  43. (8)
  44. (18)
  45. (6)
  46. (15)
  47. (114)
  48. (18)
  49. (6)
  50. (8)
  51. (66)
  52. (16)
  53. (6)
  54. (17)
  55. (5)
  56. (26)
  57. (7)
  58. (27)
  59. (7)
  60. (12)
  61. (11)
  62. (118)
  63. (31)
  64. (5)
  65. (18)
  66. (22)
  67. (9)
  68. (6)
  69. (8)
  70. (41)
  71. (10)
  72. (6)
  73. (12)
  74. (8)
  75. (5)

Друзья