Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.11.2013, 23:07   #1
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
Восклицание Исправление HTML без php-tidy

Доброго времени суток.
Пытаюсь написать скрипт который будет исправлять HTML разметку страниц, без использования php-tidy.

Пока безрезультатно, пробовал гуглить, в сети находится только примитивное и не работающее.

Типа как вот это
PHP код:
function close_dangling_tags($html){
  
#put all opened tags into an array
  
preg_match_all("#<([a-z]+)( .*)?(?!/)>#iU",$html,$result);
  
$openedtags=$result[1];
 
  
#put all closed tags into an array
  
preg_match_all("#</([a-z]+)>#iU",$html,$result);
  
$closedtags=$result[1];
  
$len_opened count($openedtags);
  
# all tags are closed
  
if(count($closedtags) == $len_opened){
    return 
$html;
  }
 
  
$openedtags array_reverse($openedtags);
  
# close tags
  
for($i=0;$i $len_opened;$i++) {
    if (!
in_array($openedtags[$i],$closedtags)){
      
$html .= '</'.$openedtags[$i].'>';
    } else {
      unset(
$closedtags[array_search($openedtags[$i],$closedtags)]);
    }
  }
  return 
$html;

dem66 вне форума Ответить с цитированием
Старый 20.11.2013, 00:18   #2
Andkorol
Старожил
 
Регистрация: 31.05.2010
Сообщений: 3,301
По умолчанию

Пробовал когда-то Jevix – в сложных ситуациях не фонтан, для простых очепяток и забытых тегов HTML сойдет.
Была ещё PHP-версия html5lib – но сейчас вроде уже не поддерживается, разрабы тоже сползли на python, как и в случае с Jevix...

Последний раз редактировалось Andkorol; 20.11.2013 в 00:23.
Andkorol вне форума Ответить с цитированием
Старый 20.11.2013, 00:50   #3
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

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

Пока родился вот такой код
PHP код:
function correction($html$cut_empty_tags=false){     
      
//Теги которые трогать не надо
      
$single_tags = array('meta'=>'','img'=>'','br'=>'','link'=>'','area'=>'','input'=>'','hr'=>'','col'=>'','param'=>'','base'=>'');
      
      
//Регулярка для получения названий тегов
      
$tag_pattern "%([/a-z]+[\-\w_]* )%x";
    
      
//Отдельно разметка и отдельно чистый текст
      
$str strip_tags($html);
      
      
//Ищем все теги в тексте и их позиции 
      
preg_match_all('/<.*?>/si'$html$elementsPREG_OFFSET_CAPTURE); 
    
      
     
// echo"<pre>\n";
      
      
$tags = array();
      
$plus 0;
      
      
//Расставляем теги по местам 
      
foreach($elements[0] as $j => $tag){
        
//Узнаем как называется текущий тег
        
preg_match($tag_pattern$tag[0], $mathes);
        
        if(isset(
$mathes[0])){
            
//Убираем спереди слеш
            
$curent ltrim($mathes[0],'/');
            
            
//Смотрим надо обрабатывать этот тег или нет
            
if(!isset($single_tags[$curent])){
                
//если тег закрывающий
                
if($mathes[0][0] == '/'){
                    
$i = (sizeof($tags)-1);
                    
                    
//Если текущий тег не первый
                    
if($j 0){

                        if(
$elements[0][$j-1][0] != null){
                            
//название предыдущего тега
                            
preg_match($tag_pattern$elements[0][$j-1][0], $mathes2);
                            
                            if(isset(
$mathes2[0])){
                                
$prev ltrim($mathes2[0],'/');
                                
                                
//текущий тег не трогаем
                                
if($prev != $curent){
                                    
//Проходимся по тегам в обратном порядке и находим открытый тег
                                    
do{
                                        if(
$tags[$i] == $curent){
                                            
$elements[0][$i][0] = null;
                                            
$tags[$i] = null;
                                            break;
                                        }

                                        
$new_tag "</".$tags[$i].">";
                                        
$new mb_strlen($new_tag);
                                            
                                        
$str str_ins(($tag[1]+$plus), $new_tag$str);
                                            
                                        
$plus += $new;
                                        
                                        
$elements[0][$i][0] = null;
                                        
$tags[$i] = null;
                                        
                                        
$i--;
                                    }while(
$i >= 0);
                                }
                            }
                        }
                        
$elements[0][$j-1][0] = null;
                    }
                    
//убираем тег из общего списка
                    
$elements[0][$j][0] = null;
                    
                    
//echo $curent."<br><br>";
                    
                    
$str str_ins(($tag[1]+$plus), $tag[0], $str);
                }else{
                    
//Тег окрывающий, значит добавляем в список    
                    
$tags[] = $curent;

                    
//Даобавляем текст и вставляем тег
                    
$str str_ins(($tag[1]+$plus), $tag[0], $str);
                }
            }else{
                
$str str_ins(($tag[1]+$plus), $tag[0], $str);
            }
        }

      }
      
//print_r($elements[0]);
      
      //print_r($tags);
      
      //echo"</pre>\n";
     
      
     // Удаляем "пустые" теги, если задано 
      
if($cut_empty_tags){ 
          
$str preg_replace('!<[^>/]+>\s*(<[^>]+>)*\s*(<[^/>]+>)*\s*</[^>]+>!si','',$str); 
      }

     return 
$str;

Понимает вот такое
Код:
<p style="color: red">
	<a href=""><i>Привет!</a>
	<br>
	<a href=""><i><u>Привет!</a>
	<br>
	<a href=""><i>Привет!</a>
</p>
<p>
	<ul>
		<li><span>1</span></li>
		<li>2</li>
		<li>3</li>
		<li>4</li>
		<li>5</li>
		<li>6</li>
		<li>7</li>
		<li>8</li>
		<li>9</li>
		<li>10</li>
	</ul>
</p>
<b>Пока</b>
пытаюс дописать чтоб понимал еще и вот такой вариант
Код:
...
</p>
<h1>
<b>Пока</b>

Последний раз редактировалось dem66; 20.11.2013 в 17:39.
dem66 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Исправление-доработка новостного движка (php) longest Фриланс 0 22.06.2012 07:59
статья - Бесплатный PHP, HTML, CSS, JavaScript редактор ? Codelobster PHP Edition Pblog Обсуждение статей 0 20.04.2012 14:50
Взов php из html или javascript (без переадресации) master3763 JavaScript, Ajax 6 24.01.2011 14:37
Преобразование HTML-PHP в PHP с запуском в командной строке. TERAB1T PHP 4 01.06.2010 14:14