Форумы портала PHP.SU » PHP » Регулярные выражения » Получить содержимое из тэга <P>, но если в содержимом не встречается тэг P

Страниц (1): [1]
 

1. antobra - 29 Июня, 2017 - 22:40:33 - перейти к сообщению
Приветствую коллеги!

Прошу помощи в регулярном выражении.

Имею регулярное, получающее содержимое тэга <P> в неком HTML коде:

Цитата:
'#\<p(\>|\s+[^\>]*\>)(.+?)\<\/p\>#is'


Все вроде должно быть хорошо, но, очень часто встречается тэги <P> вложенные в другой тэг <P>.

Например из этого HTML мы получим хороший результат из двух <P>
CODE (html):
скопировать код в буфер обмена
  1.  
  2. <body>
  3. <p>Some text here</p>
  4. <p class="info">Some text here #2</p>
  5. </body>
  6.  


Но стоит изменить на это

CODE (html):
скопировать код в буфер обмена
  1.  
  2. <body>
  3. <p class="list">
  4.     <p class="name">Text text text</p>
  5.     <p class="info">Text #2 Text # 2</p>
  6. </p>
  7. </body>
  8.  

и мы получим захваченное такое
Цитата:

1. <p class="list"> <p class="name">Text text text</p>
2. <p class="info">Text #2 Text # 2</p>


Он пропускает повторное объявление тега <p class="name">. А должен пропустить <p class="list">, приняв во внимание новое объявление тэга и парсить в нем.
Как внести в исключения в часть (.+?), чтобы он перепроверял наличие первых скобок и отбрасывал такое, как не подходящее. Или есть другие способы?

Уверен, это как-то реализуемо Улыбка
2. Строитель - 29 Июня, 2017 - 23:10:40 - перейти к сообщению
antobra, вам нужно пропускать параграф с атрибутом "list"?
3. antobra - 29 Июня, 2017 - 23:17:30 - перейти к сообщению
Строитель пишет:
antobra, вам нужно пропускать параграф с атрибутом "list"?


Нет, нужно чтобы он выдавал содержимое <p> без внутренних вложений других <p>.

Например из

CODE (html):
скопировать код в буфер обмена
  1.  
  2. <body>
  3. ...some code...
  4. <p class="any_class">
  5.     <p class="any_class" anyAttribute="anyValue">Value 1</p>
  6.     <p class="any_class" anyAttribute="anyValue">Value 2</p>
  7.     <p class="any_class" anyAttribute="anyValue">Value 3</p>
  8. </p>
  9. <p class="any_class">
  10.     <p class="any_class" anyAttribute="anyValue">Value 4</p>
  11.     <p class="any_class" anyAttribute="anyValue">Value 5</p>
  12. </p>
  13. ...some code...
  14. </body>
  15.  


Нужен результат

Цитата:

1. <p class="any_class" anyAttribute="anyValue">Value 1</p>
2. <p class="any_class" anyAttribute="anyValue">Value 2</p>
3. <p class="any_class" anyAttribute="anyValue">Value 3</p>
4. <p class="any_class" anyAttribute="anyValue">Value 4</p>
5. <p class="any_class" anyAttribute="anyValue">Value 5</p>


А в моем регулярном сейчас

Цитата:

1. <p class="any_class"><p class="any_class" anyAttribute="anyValue">Value 1</p>
2. <p class="any_class" anyAttribute="anyValue">Value 2</p>
3. <p class="any_class" anyAttribute="anyValue">Value 3</p>
4. <p class="any_class"><p class="any_class" anyAttribute="anyValue">Value 4</p>
5. <p class="any_class" anyAttribute="anyValue">Value 5</p>


Порядок тэгов не постоянен, соответственно привязать регулярное к конкретной странице нельзя.
4. Строитель - 29 Июня, 2017 - 23:29:48 - перейти к сообщению
antobra, если правильно понял
Спойлер (Отобразить)

(Добавление)
antobra, вам и теги нужно получать <p class="any_class" anyAttribute="anyValue">Value 1</p> ? В примере выше только значения.
(Добавление)
antobra, вот такой вариант вам требуется?

PHP:
скопировать код в буфер обмена
  1. /*array(5) {
  2.   [0]=>
  3.   string(56) "<p class="any_class" anyAttribute="anyValue">Value 1</p>"
  4.   [1]=>
  5.   string(56) "<p class="any_class" anyAttribute="anyValue">Value 2</p>"
  6.   [2]=>
  7.   string(56) "<p class="any_class" anyAttribute="anyValue">Value 3</p>"
  8.   [3]=>
  9.   string(56) "<p class="any_class" anyAttribute="anyValue">Value 4</p>"
  10.   [4]=>
  11.   string(56) "<p class="any_class" anyAttribute="anyValue">Value 5</p>"
  12. }*/
Если да, тогда рассмотрите этот вариант
Спойлер (Отобразить)
5. antobra - 29 Июня, 2017 - 23:50:07 - перейти к сообщению
Строитель,

Нет, атрибуты не нужны. Хотя бы значения Улыбка

В вашем варианте теги со значениями, в которых есть перенос строки, не отображаются.

Хотя.. если перед этим убирать перенос строк с помощью str_replace ( "\n", NULL, $string ), то вроде будет работать.

Попробовал убрать перенос строк. Не работает. Он все значения помещает в одно значение

PHP:
скопировать код в буфер обмена
  1.  
  2. $str = '<body>
  3. ...some code...
  4. <p class="any_class">
  5.   <p class="any_class" anyAttribute="anyValue">Value 1</p>
  6.   <p class="any_class" anyAttribute="anyValue">Value 2</p>
  7.   <p class="any_class" anyAttribute="anyValue">Value 3</p>
  8. </p>
  9. <p class="any_class">
  10.   <p class="any_class" anyAttribute="anyValue">Value 4
  11.  
  12.  
  13.   </p>
  14.   <p class="any_class" anyAttribute="anyValue">Value 5</p>
  15. </p>
  16. ...some code...
  17. </body>';
  18.  
  19. preg_match_all('~<p[^>]*>(.+)</p>~m',  str_replace ( "\n", NULL, $str ), $a);
  20.  
  21. echo '<pre>'; var_dump($a); echo '</pre>';
  22.  
  23.  
6. Строитель - 30 Июня, 2017 - 01:25:08 - перейти к сообщению
antobra, вроде бы так
Спойлер (Отобразить)
7. Строитель - 30 Июня, 2017 - 12:07:11 - перейти к сообщению
antobra, подправил шаблон "на свежую голову" Закатив глазки
8. Vladimir Kheifets - 01 Июля, 2017 - 13:28:21 - перейти к сообщению
antobra, добрый день! Вы уже получили очень хороший ответ на Ваш вопрос.
Просто ради интереса, я попробовал для решение этой задачи использовать DOMDocument class и вот, что получилось:
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. error_reporting(E_ERROR|E_PARSE);
  3.     $str = '<html><body>
  4.    ...some code...
  5.    <p class="any_class">
  6.     <p class="any_class" anyAttribute="anyValue">Value 1</p>
  7.     <p class="any_class" anyAttribute="anyValue">Value 2</p>
  8.     <p class="any_class" anyAttribute="anyValue">Value 3</p>
  9.    </p>
  10.    <p class="any_class">
  11.     <p class="any_class" anyAttribute="anyValue">Value 4
  12.  
  13.  
  14.     </p>
  15.     <p class="any_class" anyAttribute="anyValue">Value 5</p>
  16.    </p>
  17.    ...some code...
  18.    </body></html>';
  19.  
  20. $a = array();
  21. $doc = new DOMDocument();
  22. $doc->loadHTML($str);
  23. $items = $doc->getElementsByTagName('p');
  24. if(count($items)>0)
  25. {
  26.     foreach ($items as $tag)
  27.     {
  28.          $a[] = $tag->nodeValue;
  29.     }
  30.     echo '<pre>'; var_dump($a); echo '</pre>';
  31. }
  32.  
  33. /*
  34. array(7) {
  35.   [0]=>
  36.   string(7) "
  37.      "
  38.   [1]=>
  39.   string(7) "Value 1"
  40.   [2]=>
  41.   string(7) "Value 2"
  42.   [3]=>
  43.   string(7) "Value 3"
  44.   [4]=>
  45.   string(7) "
  46.      "
  47.   [5]=>
  48.   string(18) "Value 4
  49.  
  50.  
  51.      "
  52.   [6]=>
  53.   string(7) "Value 5"
  54. }
  55. */
  56. ?>

 

Powered by ExBB FM 1.0 RC1