Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: распарсить html в массив
 
 автор: Zezst   (17.12.2013 в 02:02)   письмо автору
 
 

Здравствуйте.
Помогите с разобраться. Есть html кусок. Распарсиваю его вот таким выражением:
preg_match_all("<(.+)>", $html, $var);

и местами получаются вот такие куски:
<title>Тут какая-то строка</title>

А хотелось бы их превратить в такое:
<title>
Тут какая-то строка 
</title>

Я вообще в регулярках несилен.
Изначально выражение выглядело так:
preg_match_all("|\<!--([^\>]+)\-->|i ", $html, $var);

но как я заметил, на выходе массивы почти идентичны, за исключение того, что пропадало все что между тегами.

  Ответить  
 
 автор: Zezst   (17.12.2013 в 02:20)   письмо автору
 
   для: Zezst   (17.12.2013 в 02:02)
 

</script><form action="http://www.site.com/index.php?option=com_jnews" method="post" name="modjnewsForm1"><input type="hidden"  value="1" name="subscribed[1]" />



Вот кусок понагляднее. Хотелось бы избежать потерь в конечном html, после того как из него будут удалены все <script>. Вот в таком виде бы его получить

</script>
<form action="http://www.site.com/index.php?option=com_jnews" method="post" name="modjnewsForm1">
<input type="hidden"  value="1" name="subscribed[1]" />

  Ответить  
 
 автор: duhon   (17.12.2013 в 13:04)   письмо автору
 
   для: Zezst   (17.12.2013 в 02:02)
 

ну и калабур в описании, сначала опишу про нестыковки
- "избежать потерь в конечном html", Это ты про потерю символов переноса строк?
- "после того как из него будут удалены все <script>." (в примере результата не видно что было удаленны теги script) После удаления этих тегов теряются переносы строк? Если да то лучше не восстанавливать переносы а починить механизм удаление тегов script.
- "тема: распарсить html в массив" , но по тексту ты хочешь раставить переносы строк. Так что нужно распарсить в массив или добавить переносы строк?
- "preg_match_all("<(.+)>", $html, $var);" Если разобраться то тут написано "Разбить текст на строки и поместить в массив" аналог "$var = explode("\n", $html);", Я уже не говорю что сбивает с толку ненужные метасимволы '<, >, (, )' должно выглядить примерно так '/.+/'
- зачем вообще нужно форматирование для html, браузерам это не нужно точно.

Интуиция подсказывает что ты разбиваешь html на строки (строки заносишь в массив), из этого массива удаляешь строки содаржащие script, а потом опять склеиваеш массив и получаеш инлайн html.
- Если так, то лучше удалять script так
<?php $html preg_replace('#<script.*</script>#siU'''$html);

- Можно при склеивани массива добавить "\n" (если кодировка utf8 иначе "\r\n") пример
<?php $var implode("\n"$array);

- (нерекомендую) Можно сделать так что бы массив уже содержал переносы строк, например заменить preg_match_all("<(.+)>", $html, $var); на
<?php preg_match_all('/^.*\R/m' $html$var);

- (нерекомендую) Можно инлайн html попытаться исправить
<?php $var preg_replace('/></'">\n<"$html);


Ну и под конец, всегда при мыслях "html, сложно, regex" лучше использовать html парсеры (совместно с regex). (поиск по гуглу "html парсер php")

  Ответить  
 
 автор: Zezst   (17.12.2013 в 14:43)   письмо автору
 
   для: duhon   (17.12.2013 в 13:04)
 

За совет, '#<script.*</script>#siU', спасибо. Сейчас буду пробовать под свои нужды присособить.
Про html парсеры знаю, но они мало помогают самообучению.
Мое первое выражение дает такой массив:
Array
(
    [0] => <script src="/media/system/js/mootools-core.js" type="text/javascript"></script>
    [1] => <script src="/media/system/js/core.js" type="text/javascript"></script>
    [2] => <script src="/media/system/js/modal.js" type="text/javascript"></script>
    [652] => <script language="javascript" type="text/javascript">
    [653] => <!--
    [654] => function submitjnewsmod1(formname, url) {
    [849] => </script><form action="http://www.smithsdetection.com/index.php?option=com_jnews" method="post" name="modjnewsForm1"><input type="hidden"  value="1" name="subscribed[1]" />

Почти идеально. Вот только в последней строчке не то, что хотелось бы получить. В идеале последняя строчка должна бы выглядеть так:
    [849] => </script>
    [850] => <form action="http://www.smithsdetection.com/index.php?option=com_jnews" method="post" name="modjnewsForm1">
    [851] => <input type="hidden"  value="1" name="subscribed[1]" />

И да. Прощу прощения за сбивчивые объяснения. Красиво писать не мой конек.

P.S. <script> у меня не выкидывается совсем. Он удаляется только из основного html, но сам складывается в соседний массив.

  Ответить  
 
 автор: duhon   (17.12.2013 в 17:12)   письмо автору
 
   для: Zezst   (17.12.2013 в 14:43)
 

попробуй как я писал выше, только по очереди
<?php
//находим скипты
preg_match_all("#<script.*</script>#siU"$html$array_scrit);
//удаляем скипты
$html preg_replace('#<script.*</script>#siU'''$html);
//пытаемся немного отформатировать html
$html preg_replace('/></'">\n<"$html);
//разбивает на строки
$array_html explode("\n"$html);

  Ответить  
 
 автор: Zezst   (17.12.2013 в 17:32)   письмо автору
 
   для: duhon   (17.12.2013 в 17:12)
 

Спасибо вам за помощь, ваше выражение сработало идеально.
Я его в вот такое превратил:
preg_match_all("#<script.*</script>|<(.+)>|-->|(.*)#siU", $smith_site, $regs2);

Вот прям почти то, что нужно. Трабл с последним условием (.*). Оно разбивает каждый символ в отдельную ячеку массива:
    [170] => <title>
    [171] => 
    [172] => C
    [173] => 
    [174] => B
    [175] => 
    [176] => R
    [177] => 
    [178] => N
    [179] => 
    [180] => E
    [181] => 
    [182] =>  
    [183] => 
    [184] => t
    [185] => 
    [186] => h
    [187] => 
    [188] => r
    [189] => 
    [190] => e
    [191] => 
    [192] => a
    [193] => 
    [194] => t
    [195] => 
    [196] =>  
    [197] => 
    [198] => d
    [199] => 
    [200] => e
    [201] => 
    [202] => t
    [203] => 
    [204] => e
    [205] => 
    [206] => c
    [207] => 
    [208] => t
    [209] => 
    [210] => i
    [211] => 
    [212] => o
    [213] => 
    [214] => n
    [215] => 
    [216] =>  
    [217] => 
    [218] => s
    [219] => 
    [220] => o
    [221] => 
    [222] => l
    [223] => 
    [224] => u
    [225] => 
    [226] => t
    [227] => 
    [228] => i
    [229] => 
    [230] => o
    [231] => 
    [232] => n
    [233] => 
    [234] => s
    [235] => 
    [236] =>  
    [237] => 
    [238] => f
    [239] => 
    [240] => r
    [241] => 
    [242] => o
    [243] => 
    [244] => m
    [245] => 
    [246] =>  
    [247] => 
    [248] => S
    [249] => 
    [250] => m
    [251] => 
    [252] => i
    [253] => 
    [254] => t
    [255] => 
    [256] => h
    [257] => 
    [258] => s
    [259] => 
    [260] =>  
    [261] => 
    [262] => D
    [263] => 
    [264] => e
    [265] => 
    [266] => t
    [267] => 
    [268] => e
    [269] => 
    [270] => c
    [271] => 
    [272] => t
    [273] => 
    [274] => i
    [275] => 
    [276] => o
    [277] => 
    [278] => n
    [279] => </title>

Если не трудно, помогите описать его так, что бы получилось:
    [170] => <title>
    [171] => CBRNE threat detection solutions from Smiths Detection
    [172] => </title>

  Ответить  
 
 автор: Zezst   (17.12.2013 в 15:17)   письмо автору
 
   для: duhon   (17.12.2013 в 13:04)
 

Еще раз спасибо вам за выражение. Проверил:
preg_match_all("#<script.*</script>#siU", $smith_site, $regs2);

Вырезает идеально. Одно плохо, приходится дважды вызывать preg_match_all()

Изначално как то так оно задумывалось:
<?php
preg_match_all
("<(.+)>"$html$regs2);//!!!
$ht '';
        
$scri 0;
foreach (
$regs2[0] as $key => $value) {
    
$value trim($value);
    if(!empty(
$value)) {
        if (
stripos($value'<link') !== false) {
            
$link[] = $value;
            continue;
        }
if (
stripos($value'<script') !== false || $scri === 1) {
    if (
stripos($value'</script') !== false) {

        
$scri 0;
            
$script[] = $value;
            continue;
        }
        
$scri 1;
            
$script[] = $value;
            continue;
}
    
$ht .= $value "\n";
    }
}
print_r($ht);
print_r($script);
print_r($link);
?>

  Ответить  
 
 автор: Zezst   (18.12.2013 в 09:56)   письмо автору
 
   для: Zezst   (17.12.2013 в 02:02)
 

Постепенно добрался до такого варианта:
preg_match_all("#<!--.*-->|<script.*</script>|<.+>|.[^<>]{0,}+#msiU", $smith_site, $regs3);

теперь, как и хотелось, получил:
    [38] => <title>
    [39] => CBRNE threat detection solutions from Smiths Detection
    [40] => </title>

Но обнаружился еще один неприятный момент, который бы хотелось исправить:

    [120] => <label for="jflanguageselection" class="jflanguageselection">
    [121] => JFMSELECT
    [122] => </label>
    [123] => 

    [124] => <select name="lang"  class="jflanguageselection" size="1" onchange="document.location.replace(this.value);">

По всему массиву вылезли пустые элементы. Хотелось избавится от них в том же выражении. Если кто может помочь, буду очень признателен.

  Ответить  
 
 автор: duhon   (18.12.2013 в 15:06)   письмо автору
 
   для: Zezst   (18.12.2013 в 09:56)
 

пробуй так
<?php preg_match_all('#<!--.*-->|<script.*</script>|<.+>|(?!\s+?<|\Z)[^<>]+?#siU'$smith_site$regs3);


- ИМХО ужасно использовать модификатор U (ленивый по умолчанию), всегда удобней однозначно читать регулярку, а не помнить что поведение квантификаторов инвертированно, и такой модификатор только для php
- [^<>]{0,}+ это равно [^<>]*+ и видимо супержадный режим ты использовал из за модификатора U
- если уже так издеваться регулярками, то можно перейти на следующий уровень http://www.php.net/manual/ru/regexp.reference.recursive.php

  Ответить  
 
 автор: Zezst   (18.12.2013 в 16:57)   письмо автору
 
   для: duhon   (18.12.2013 в 15:06)
 

Ух! Спасибо вам огроменное. Идеально. То что доктор прописал.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования