[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: регулярка, как лучше?
SnowWind
Салют, имеется такой вот код, причём строк в таблице может быть и 10 и 20.

<table class="new">
<tr
class="h">
<td
class="c_i"><a name='1'></a><a href=""><img src="" /></a></td>
<td
class="c_n" class="f14"><b>Toyota</b></td>
<td
class="f14">2009</td>
<td
class="f14">1.5</td>
<td>

автомат<br/>передний<br/> </td>
<td>
43, б/п</td>
<td><center></center></td>
<td>
<span
class="f14">535 000 руб.</span><br/>
</td>
</tr>
<tr
class="h">
<td
class="c_i"><a name='1'></a><a href=""><img src="" /></a></td>
<td
class="c_n" class="f14"><b>Toyota</b></td>
<td
class="f14">2009</td>
<td
class="f14">1.5</td>
<td>

автомат<br/>передний<br/> </td>
<td>
43, б/п</td>
<td><center></center></td>
<td>
<span
class="f14">555 000 руб.</span><br/>
</td>
</tr>
<tr
class="h">
<td
class="c_i"><a name='1'></a><a href=""><img src="" /></a></td>
<td
class="c_n" class="f14"><b>Toyota</b></td>
<td
class="f14">2009</td>
<td
class="f14">1.5</td>
<td>

автомат<br/>передний<br/> </td>
<td>
43, б/п</td>
<td><center></center></td>
<td>
<span
class="f14">575 000 руб.</span><br/>
</td>
</tr>
<tr
class="h">
<td
class="c_i"><a name='1'></a><a href=""><img src="" /></a></td>
<td
class="c_n" class="f14"><b>Toyota</b></td>
<td
class="f14">2009</td>
<td
class="f14">1.5</td>
<td>

автомат<br/>передний<br/> </td>
<td>
43, б/п</td>
<td><center></center></td>
<td>
<span
class="f14">535 000 руб.</span><br/>
</td>
</tr>
</table>


Как выбрать ВСЕ строки таблицы где цена = 535
Т.е по
<span class="f14">535 000 руб.</span><br/>


preg_match_all('~^(?:.*)(<tr.*<span class="f14">)(535)(.*</span>.*</tr>)(?:.*)~iUs', $html, $result);


Получу только 1 первую строку, не могу понять а как забрать остальные?

Или забирать до конца пока не встречу </table>, а потом проверка по массиву на наличие данных, цикл и опять preg_match_all ?

Подскажите решение.



Спустя 4 часа, 5 минут, 20 секунд (24.09.2012 - 15:02) Placido написал(а):
preg_match_all('#<tr class="h">((?<!</tr>).)*?<span class="f14">535 000 руб\.</span>.*?</tr>#sui', $html, $result);

Спустя 1 час, 1 минута, 6 секунд (24.09.2012 - 16:03) SnowWind написал(а):
что-то мне подсказывает, что что-то тут не так smile.gif

Спустя 6 минут, 50 секунд (24.09.2012 - 16:10) killer8080 написал(а):
SnowWind
зачем привязываться к таблице, когда нужен только <span class="f14">535 000 руб.</span> ?

Спустя 18 минут, 2 секунды (24.09.2012 - 16:28) SnowWind написал(а):
по идее да, можно и так.
Но тем не менее нужно что бы preg_match запоминал все вхождения шаблона из исходника, а не только первый попавшийся, вот я не знаю как сделать

Спустя 9 минут, 41 секунда (24.09.2012 - 16:38) killer8080 написал(а):
SnowWind
а чем вариант Placido не устроил?

Спустя 5 минут, 14 секунд (24.09.2012 - 16:43) SnowWind написал(а):
я чёт его не понял, если честно, но думаю он предложил использовать ретроспективную негативную проверку на соответствие всего кроме </tr>
Так а мне нужно вперёд.

Спустя 7 минут, 48 секунд (24.09.2012 - 16:51) SnowWind написал(а):
и самое главное сохраняться строки должны в соответствии с шаблоном. Т.е всё с числом 535
все строки из всего исходника соответствующие паттерну, а не первое совпадение

Спустя 18 минут, 14 секунд (24.09.2012 - 17:09) SnowWind написал(а):
в общем либо я не понимаю тут чего-то либо без цикла никак не сделать

Спустя 3 часа, 8 минут, 32 секунды (24.09.2012 - 20:18) Placido написал(а):
Цитата (SnowWind @ 24.09.2012 - 16:43)
думаю он предложил использовать ретроспективную негативную проверку на соответствие всего кроме </tr>
Так а мне нужно вперёд.

Неправильный вывод. В $result будут все строки "<tr class="h">...</tr>", содержащие "<span class="f14">535 000 руб.</span>".

Спустя 1 час, 12 минут, 39 секунд (24.09.2012 - 21:30) killer8080 написал(а):
Цитата (SnowWind @ 24.09.2012 - 16:43)
я чёт его не понял, если честно, но думаю он предложил использовать ретроспективную негативную проверку на соответствие всего кроме </tr>
Так а мне нужно вперёд.

Зачем гадать, когда можно взять, и проверить? Он дал рабочий вариант.

Спустя 16 часов, 57 минут (25.09.2012 - 14:27) SnowWind написал(а):
да работает, но этот код мне мало чем помог, я всёравно не понял как это и почему работает, а можно объяснить логику?

Спустя 25 минут, 41 секунда (25.09.2012 - 14:53) killer8080 написал(а):
'((?<!</tr>).)*?'

здесь может быть любой текст, в котором нет </tr>
'</span>.*?</tr>'

здесь любой текст после спана, до первого попавшегося </tr>. То есть, захватывается одни ряд таблицы, содержащий <span class="f14">535 000 руб.</span>

Спустя 1 час, 6 минут, 10 секунд (25.09.2012 - 15:59) SnowWind написал(а):
но это
((?<!</tr>).)
говорит что нужно искать влево от шаблона, но сначала нужно найти само вхождение шаблона т.е <span class="f14">535 000 руб\.</span>.*?</tr>
Причём после спан любое вхождение любого количества символов, НО до того момента пока не встретится первый раз </tr>

Так теперь пляшем влево от начала спана перед которым любое кол-во, любых симолов, пока не встретим попутно сохраняя любой символ ((?<!</tr>).)

Но почему ещё дальше этой "проверки назад" опять идёт шаблон? :huh:

Спустя 7 минут, 41 секунда (25.09.2012 - 16:07) killer8080 написал(а):
Цитата (SnowWind @ 25.09.2012 - 15:59)
Но почему ещё дальше этой "проверки назад" опять идёт шаблон?

а почему он не может идти?

Спустя 19 минут, 7 секунд (25.09.2012 - 16:26) SnowWind написал(а):
ну как бы это не логично мне кажется
мы ему уже сказали "иди влево от
*?<span class="f14">535 000 руб\.</span>.*?</tr>
записывая всё что найдёшь, ОСТАНОВИСЬ когда достигнешь </tr>"
Потом ещё говорим "ищи вхождение символов
<tr class="h">
" которые он уже себе записал, вот зачем не понятно.

Так же не понятно как он выбрал все строки tr из ВСЕЙ таблицы, где обнаружил такой набор символов -
<span class="f14">535 000 руб\.</span>
ведь ему же указали на ленивый поиск вот тут
.*?</tr>#sui'
т.е дальше первого вхождения он сунуться не должен был и выбирать всё назад, там где строк таблицы нет

Спустя 17 минут (25.09.2012 - 16:43) killer8080 написал(а):
Цитата (SnowWind @ 25.09.2012 - 16:26)
ну как бы это не логично мне кажется
мы ему уже сказали "иди влево от
*?<span class="f14">535 000 руб\.</span>.*?</tr>
записывая всё что найдёшь, ОСТАНОВИСЬ когда достигнешь </tr>"

Наоборот, все что не содержит </tr>

Цитата (SnowWind @ 25.09.2012 - 16:26)
ак же не понятно как он выбрал все строки tr из ВСЕЙ таблицы, где обнаружил такой набор символов -
<span class="f14">535 000 руб\.</span>
ведь ему же указали на ленивый поиск вот тут
.*?</tr>#sui'

Знак вопроса, перед квантификатором инвертирует режим поиска .*?

Спустя 10 минут, 29 секунд (25.09.2012 - 16:54) SnowWind написал(а):
перед каким он квантификатором? этим - "<" ?
и что значит инвертирует режим поиска?

В смысле он же идёт ПОСЛЕ квантификатора

Спустя 16 часов, 39 минут, 42 секунды (26.09.2012 - 09:33) killer8080 написал(а):
Цитата (SnowWind @ 25.09.2012 - 16:54)
В смысле он же идёт ПОСЛЕ квантификатора

.*?

звездочка - квантификатор, знак вопроса после неё инвертирует жадность. Поскольку модификатора U нет, по умолчанию поиск жадный, соответственно в этом месте он инвертируется, и становиться не жадным.

Спустя 5 минут, 50 секунд (26.09.2012 - 09:39) SnowWind написал(а):
не совсем в этом, а когда встретит </tr> инвертируется и идёт назад, а потом мы ему указываем, что ищи ещё левее, но как он выбирает последуещие теги, которые идут ПОСЛЕ инвертации, ведь туда мы ему как бы "запретили суваться"?

Спустя 37 минут, 20 секунд (26.09.2012 - 10:16) killer8080 написал(а):
вот эта конструкция
'<tr class="h">((?<!</tr>).)*?<span class="f14">'
означает, что будет захвачен <tr class="h">, и <span class="f14">, между которыми может быть любой текст, в котором нет </tr>

Спустя 43 минуты, 39 секунд (26.09.2012 - 11:00) SnowWind написал(а):
ну это понятно я не про то
ещё раз мы дошли до тега </tr> и развернули поиск в сторону <tr class="h"> перед которым идёт уже <table> вопрос в том как он находит остальные, ведь остальные стоят ПОСЛЕ того как мы его развернули (когда он встретил </tr>)

Спустя 7 минут, 46 секунд (26.09.2012 - 11:08) killer8080 написал(а):
Цитата (SnowWind @ 26.09.2012 - 11:00)
и развернули поиск в сторону <tr class="h"> перед которым идёт уже <table> вопрос в том как он находит остальные

А почему он не должен находить? Обработка патерна не заканчивается на обработке утверждений (assertion)
http://php.net/manual/ru/regexp.reference.assertions.php

Спустя 1 день, 21 час, 16 минут, 54 секунды (28.09.2012 - 08:25) SnowWind написал(а):
а как далеко он будет искать соответствие утверждения?
н-р
$a = 'abcdefghiklmnop';
preg_match_all ('~{?<=a}k~', $a, $b);


в этом случае утверждение будет верно? Или 'а' должно идти сразу перед 'k', или количество символов до нахождения 'а' не имеет значения?

Спустя 31 минута, 24 секунды (28.09.2012 - 08:56) Placido написал(а):
Цитата (SnowWind @ 28.09.2012 - 08:25)
$a = 'abcdefghiklmnop';
preg_match_all ('~{?<=a}k~', $a, $b);
в этом случае утверждение будет верно? Или 'а' должно идти сразу перед 'k', или количество символов до нахождения 'а' не имеет значения?

"а" должно идти сразу перед "k". Будет искать все "k", непосредственно перед которыми есть "a". Поэтому в приведенном примере не найдет ничего.
Только скобки должны быть круглые, а не фигурные.

Спустя 5 минут, 3 секунды (28.09.2012 - 09:01) SnowWind написал(а):
Цитата (Placido @ 28.09.2012 - 05:56)
Только скобки должны быть круглые, а не фигурные.

ага точно smile.gif

немного прояснилось, сейчас ещё попробую smile.gif

Спустя 43 минуты, 21 секунда (28.09.2012 - 09:45) SnowWind написал(а):
кстати на счёт круглых скобок, почему в варианте Placido строка поиска не обрамлена скобками? А результаты сохраняются. huh.gif

Спустя 23 минуты, 11 секунд (28.09.2012 - 10:08) killer8080 написал(а):
Цитата (SnowWind @ 28.09.2012 - 09:45)
кстати на счёт круглых скобок, почему в варианте Placido строка поиска не обрамлена скобками? А результаты сохраняются.

Скобки нужны, когда нужно выдернуть конкретный фрагмент из шаблона.

Спустя 5 часов, 13 минут, 5 секунд (28.09.2012 - 15:21) SnowWind написал(а):
а без скобок результат всёравно сохранится?

Спустя 3 минуты, 51 секунда (28.09.2012 - 15:25) killer8080 написал(а):
Цитата (SnowWind @ 28.09.2012 - 15:21)
а без скобок результат всёравно сохранится?

выведи массив совпадений, и сам все увидишь wink.gif

Спустя 1 день, 3 часа, 37 минут, 29 секунд (29.09.2012 - 19:02) SnowWind написал(а):
Вот тут такой вариант вообще не работает

<?php
$url = 'http://chita.drom.ru/toyota/corolla_fielder/?minprice=500000&maxprice=505000&go_search=2';

$ch = curl_init();

curl_setopt($ch, CURLOPT_PROXY, '217.76.35.238:3128');

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo $html = curl_exec($ch);

preg_match_all('#<tr class="h">((?<!</tr>).)*?<span class="f14">500 000 руб\.</span>#sui', $html, $result);
echo '<br>'.print_r($result).'<br>';

curl_close($ch);

?>


единственное что тут я смог добиться, это только достать всю таблицу -
~<table class="newCatList visitedT">.*</table>~sUi

причём именно с такими модификаторами. интересно, что если написать
~<table class="newCatList visitedT">.*?</table>~si
эффекта никакого, а д.б равноценно предыдущей записи.

В общем не выбирает он тут строки нифига :(

Спустя 25 минут, 29 секунд (29.09.2012 - 19:28) killer8080 написал(а):
SnowWind
а в html заглянуть религия не позволяет? Там нет
<span class="f14">500 000 руб.</span>

там
<span class="f14">500&nbsp;000&nbsp;руб.</span>

Спустя 8 часов, 40 минут, 2 секунды (30.09.2012 - 04:08) SnowWind написал(а):
я так и писал, просто сайт автоматически поставил пробелы
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.