Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Регулярное выражение, проблема с "жадностью" / 7 сообщений из 7, страница 1 из 1
28.11.2014, 22:08
    #38820051
Jeka-x87
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Регулярное выражение, проблема с "жадностью"
Есть текст:
Код: html
1.
2.
3.
<h1>text1</h1>
<h1>text2</h1><div>textdiv1</div>
<h1>text3</h1><div>textdiv2</div> 



Необходимо выделить этементы типа <h1>***</h1><div>***</div>, т.е. результатом должно быть 2 строки:
Код: html
1.
2.
<h1>text2</h1><div>textdiv1</div>
<h1>text3</h1><div>textdiv2</div>



Моё регулярное выражение:
Код: html
1.
/<h1>.*?<\/h1><div>.*?<\/div>/i



В результате находит 2 соответствия:
Код: html
1.
2.
<h1>text1</h1><h1>text2</h1><div>textdiv1</div>
<h1>text3</h1><div>textdiv2</div>



Не могу понять, почему захватывается текст <h1>text1</h1> ?

Код PHP:
Код: php
1.
2.
3.
4.
5.
6.
$string = '<h1>text1</h1><h1>text2</h1><div>textdiv1</div><h1>text3</h1><div>textdiv2</div>';
$pattern = '/<h1>.*?<\/h1><div>.*?<\/div>/i';
preg_match_all($pattern, $string, $matches);
foreach ($matches[0] as $match) {
   echo htmlentities($match) . '<br>';
}
...
Рейтинг: 0 / 0
28.11.2014, 23:42
    #38820110
MikkiMouse
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Регулярное выражение, проблема с "жадностью"
Jeka-x87,

DOM + XPath
...
Рейтинг: 0 / 0
28.11.2014, 23:44
    #38820112
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Регулярное выражение, проблема с "жадностью"
Jeka-x87 Не могу понять, почему захватывается текст <h1>text1</h1> ?

Потому что фрагмент <h1>text1</h1><h1>text2</h1> отлично подходит под шаблон <h1>.*?<\/h1> , потому как точка - это любой символ.
...
Рейтинг: 0 / 0
29.11.2014, 12:21
    #38820218
JeStone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Регулярное выражение, проблема с "жадностью"
vkle,
Не знаю почему именно так происходит, но дело в символе "/".

Регулярка:
<h1>[a-zA-Z0-9<>_]*?<\/h1><div>
Результат:
Array
(
[0] => Array
(
[0] => <h1>text2</h1><div>
[1] => <h1>text3</h1><div>
)

)


Регулярка:
]<h1>[a-zA-Z0-9<>_\/]*?<\/h1><div>
Результат:
Array
(
[0] => Array
(
[0] => <h1>text1</h1><h1>text2</h1><div>
[1] => <h1>text3</h1><div>
)

)


И это не баг, в JavaScript так же.
...
Рейтинг: 0 / 0
29.11.2014, 13:56
    #38820259
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Регулярное выражение, проблема с "жадностью"
Может как-то так попробовать?
Код: php
1.
/<h1>[^<]+<\/h1><div>[^<]+<\/div>/i
...
Рейтинг: 0 / 0
29.11.2014, 14:00
    #38820260
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Регулярное выражение, проблема с "жадностью"
Хотя... Если задача состоит только в том, чтобы проигнорировать в итоговом массиве первую строку из трех исходных, я бы наверно сделал експлод текста в массив, а потом выкинул из него нулевой элемент. Или исходный текст в одной строке?
...
Рейтинг: 0 / 0
29.11.2014, 14:24
    #38820264
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Регулярное выражение, проблема с "жадностью"
слушай, профессор, давай подругому. ты хочешь сказать что результат не соответсвует твоему выражению???

или идём другим путём. ты указал ленивую хвантификацию, ок

идём регуляркой по тексту.

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

ок...ищем , находим тег закрытия(н1) и дальше должен стоять тег див - опа, а у нас другой тег н1 стоит.

счего парсер должен решить, ах вот оно как, надо забыть теперь про тег н1 первый, пан профессор не хотел его находить?

тоесть
у меня регулярка

a.*?bc.*?d

и текст
a1ba2bc3d

вот обясни на пальцах, почему под эту регулярку не должна попасть вся строка, а только часть
a2bc3d
???

тоесть я к тому, что возьмём за основу, твоя регулярка не однозначная.
более того, рузельтат выводиться логичным.
ибо регулярки ищут максимальной длинны совпадение,
я имею ввиду, что в большинстве случаев при двузначном толковании, будет найден тот вариант что длиннее.

ревнивая жадная ленивая ....это лишь влияет на порядок сканирования строки.

жадная при поиске .*a - сначала захватит всю строку, потом будет отпускать по одному символу, пока не встретит а

ленивая, сначала захватит 0 символов, потом будет брать по одному сиволу пока не встретит а

с єтим мы согласимся оба.
но у тебя после .*? стоит не а, а стоит аб (несколько статичных символов)
щитай что это один символ, ленивая ищет(и таки оно ищет весь статичный кусок!!!!

тоесть
<h1>.*?<\/h1><div>
алгоритм идентичен a.*?b

ищем первый статичный кусок, нашли, берём ноль символов, смотрим - дальше стоит статичный кусок? нет, один символ под точку со звездой ушол, теперь стоит второй статичный кусок.... и так до тех пор пока не найдёт

понимаешь??? это ты акцентируешь внимание на закрытии открытии тега.

для машины, есть подстрока начала, дальше что угодно, подсрока середины, дальше что угодно, и подстрока окончания

начало = <h1>
что-то
середина <\/h1><div>
что-то
концовка </div>

вот что ты задал, вот оно тебе и нашло.
оно бы искало как хочешь ты, если бы поиск шол справа на лево по строке :)
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Регулярное выражение, проблема с "жадностью" / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]