Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   проблемы с рекурсией в PCRE (php) (https://forum.antichat.xyz/showthread.php?t=105740)

slesh 11.02.2009 11:17

проблемы с рекурсией в PCRE (php)
 
очень срочно нужно написать регулярное выражение чтобы отпарсить определенную строку. Сложность в том что каждая подстрока имеет еще другую последовательность разной длинны.
Примерно вот
Код HTML:

<div>
<h1>STR_1<h1>
  <h2>STR_2</h2>
  <ol>
    <li> STR_3
    <li> STR_4
    <li> STR_5
  </ol>
</div>

<div>
<h1>STR_1<h1>
  <h2>STR_2</h2>
  <ol>
    <li> STR_3
    <li> STR_4
    <li> STR_5
    <li> STR_6
    <li> STR_7
  </ol>
</div>

вот мне нужно отпарсить и получить все данные на месте помеченным STR_

Pashkela 11.02.2009 17:56

Почему у тебя тег <li> не закрыт </li>??? Уже припарился я

Gifts 11.02.2009 19:16

slesh Тут рекурсивные регулярки НЕ нужны (только замедлят), вначале получаем все что между дивов, а потом уже получаем все STR

PHP код:

<pre><?
$in
=<<<HTT
<div>
<h1>STR_1a</h1>
  <h2>STR_2a</h2>
   <ol>
     <li> STR_3a
     <li> STR_4a
     <li> STR_5a
   </ol>
</div>

<div>
<h1>STR_1b</h1>
  <h2>STR_2b</h2>
   <ol>
     <li> STR_3b
     <li> STR_4b
     <li> STR_5b
     <li> STR_6b
     <li> STR_7b
   </ol>
</div>
HTT;
//echo $in;
preg_match_all('~<div>(.+)</div>~Usi',$in,$result);
foreach(
$result[1] as $i => $one)
{
    
// Получсаем заголовки
    
preg_match('~<h1>([\s\S]*)</h1>\s*<h2>([\s\S]*)</h2>~Ui',$one,$head);
    
// Выдираем все элементы списка
    
preg_match_all('~<li> ([^\r\n]*)~i',$one,$tmp);
    echo 
'<hr>'.$head[1].'<hr>'.$head[2].'<hr>';
    
print_r($tmp[1]);
}
?>


slesh 12.02.2009 00:25

2 Pashkela: Как есть так есть. Да и вообщето </li> - необязателен (читай доки ;))
2 Gifts: спс за код. Просто думал что возможно это сделать в один проход :)

Chaak 12.02.2009 00:50

Ну вы пиздецы..

PHP код:

preg_match_all("#<li>(.*?)(\n|<)#i",$text,$res); 
print_r($res); 

не рулит?

.:EnoT:. 12.02.2009 00:56

Можно и одним проходом, главное составить нужную регулярку. Если бы у тебя тег li был закрыт, то регулярка выглядела бы так:

PHP код:

<?php

$str 
= <<<STR

<div>
<h1>STR_1a</h1>
  <h2>STR_2a</h2>
   <ol>
     <li> STR_3a</li>
     <li> STR_4a</li>
     <li> STR_5a</li>
   </ol>
</div>

<div>
<h1>STR_1b</h1>
  <h2>STR_2b</h2>
   <ol>
     <li> STR_3b</li>
     <li> STR_4b</li>
     <li> STR_5b </li>
     <li> STR_6b</li>
     <li> STR_7b</li>
   </ol>
</div>

STR;


preg_match_all('#<(h[12]{1}|li)>([^>]*)</\\1>#s'$str$out);
print_r($out[2]);

?>


Или если всё таки они не закрыты, то парсим вот так:

PHP код:

<?php

$str 
= <<<STR

<div>
<h1>STR_1a</h1>
  <h2>STR_2a</h2>
   <ol>
     <li> STR_3a
     <li> STR_4a
     <li> STR_5a
   </ol>
</div>

<div>
<h1>STR_1b</h1>
  <h2>STR_2b</h2>
   <ol>
     <li> STR_3b
     <li> STR_4b
     <li> STR_5b
     <li> STR_6b
     <li> STR_7b
   </ol>
</div>

STR;


preg_match_all("#<(h[12]{1}|li)>([^>]*)(</h[12]{1}>|\r\n)#s"$str$out);
print_r($out[2]);

?>


Хитрый финт ушами))

slesh 12.02.2009 00:57

2 ChaaK скажено же что нужно не только то, что в LI но и заголовки.
И вообще эта тема уже неактуально ибо строчность уже пропала.

.:EnoT:. 12.02.2009 00:58

Цитата:

Сообщение от ChaaK
Ну вы пиздецы..

PHP код:

preg_match_all("#<li>(.*?)(\n|<)#i",$text,$res); 
print_r($res); 

не рулит?

не рулит, т.к. ему нужно получить текст не только между тегами LI, но и между дивами


Время: 01:16