Ru-Board.club
← Вернуться в раздел «Web-программирование»

» PHP: Регулярные выражения (RegExp, Regular, eregi, preg)

Автор: Delphi6
Дата сообщения: 08.09.2006 17:00
Прошу помочь, так как я сам лично полностью запутался и ни как не могу разобраться в чем проблема. У меня есть вот такое регулярное выражение:

Код: preg_match_all("#<table.*?>(.*?)</table>#is", $this->pageContent, $tables);
Автор: Brodyaga
Дата сообщения: 08.09.2006 17:53
Delphi6
Решение второй проблемы я вижу таким:
$buffer = preg_replace("#%%ITEM0%%#ise", '$value', $buffer);
Над первой проблемой думаем..
Автор: Delphi6
Дата сообщения: 08.09.2006 18:19
Brodyaga
Огромное спасибо, действительно заработало Сейчас читаю про данный модификатор (e)

По поводу второй проблемы, вот исходник страницы:
http://proxy-list.org/ru-board/table/test.htm

Вот сам скрипт:

Код: <?php
$content = implode('', file("test.htm"));
preg_match_all("#<table.*?</table>#is", $content, $tables);
print_r($tables[0]);
?>
Автор: Brodyaga
Дата сообщения: 08.09.2006 19:54
Прошу ткнуть пальцем в выдаче test.php где ошибка, не вижу в упор-два элемента-две таблицы

Добавлено:
Кстати, у меня проклёвывается мысль, что нужно использовать $tables[1] чтобы не было лишних совпадений.
Автор: Delphi6
Дата сообщения: 08.09.2006 20:45
Brodyaga
На страничке:

всего 3 таблицы а не 2 как показывает скрипт, нижняя правильно отображается но если вы обратите внимание на верхнюю то она находиться еще в одной не правильно созданной таблице. Мне нужно что бы вот эта первая таблица отображалась корректно, привожу код из работы скрипта:

Код: Array
(
[0] => <table border="0" cellpadding="0" cellspacing="0" height="30" width="780">
<tbody>
<tr>
<td class="td1" width="95%">
Sites: <font color="#ccff66" size="3">All Sites</font><br>
Period: <font color="#ccff66" size="3">01-09-2006 - 15-09-2006</font><br>
<br>

<table align="center" border="1" bordercolor="#666666" cellpadding="2" cellspacing="1" width="100%">
<tbody>
<tr align="center" bgcolor="#666666">
<td style="color: rgb(255, 204, 0);" height="15">&nbsp;</td>
<td style="color: rgb(255, 204, 0);" height="15">&nbsp;</td>
<td colspan="2" style="color: rgb(255, 204, 0);" height="15">&nbsp;</td>
<td colspan="2" style="color: rgb(255, 204, 0);" height="15">&nbsp;</td>
...
</tr>

</tbody>
</table>
[1] => <table align="center" border="1" bordercolor="#666666" cellpadding="2" cellspacing="1" width="100%">
<tbody>
...
Автор: Brodyaga
Дата сообщения: 08.09.2006 21:52

Код:
preg_match_all("#<table.*?>(.*?)</table>?#is", $content, $tables);
print_r($tables[0]);
Автор: Delphi6
Дата сообщения: 08.09.2006 22:36
Brodyaga
А у меня это не работает:
<?php
$content = implode('', file("test.htm"));
preg_match_all("#<table.*?>(.*?)</table>?#is", $content, $tables);
print_r($tables[0]);
?>
в чем проблемы? Проверьте может вы что-то не дописали?

Cheery
Вот код который я поправил и вот что он выдает:

Код: <?php
$content = implode('', file("test.htm"));
preg_match_all("#<table(.*?)>(.*?)</table>#is", $content, $tables);
foreach ($tables[2] as $key=>$value) {
echo "Table #$key<br>\r\n<table {$tables[1][$key]}>".$tables[2][$key]."</table>\r\n<hr>\r\n";
}

$content = '<td>value1<td>value2<td>value3<td>value4<td>';
preg_match_all("#<td>(.*?)<td>#is", $content, $values);
print_r($values[1]);
?>
Автор: KADABRA
Дата сообщения: 09.09.2006 10:39
Delphi6
В перел регулярные выражения более гибкие.
ИМХО это было бы легче на перле и сделать. Там как раз и есть рекурсивные регеспы.

А на ПХП получается вот такой вот изврат.

<?php
$content = file_get_contents("Delphi_test.html");
preg_match_all("#<table.*?(<table.*?(<table.*?</table>.*?)*</table>.*?)*</table>#is", $content, $tables);
print_r($tables);
?>

Т.е. мы сами определяем максимальный уровень вложенности. Для данного примера это 3.
Автор: Delphi6
Дата сообщения: 09.09.2006 12:27
KADABRA
Если многие согласны с вашим решением, то тогда остается только одно, после того как найдутся все таблицы, вручную рекурсивно искать таблицы в уже полученных таблицах Хотя я не могу скрыть недовольство и такой большой промах со стороны рег. выражений! Как можно было не учесть такого банального варианта?
Автор: Brodyaga
Дата сообщения: 09.09.2006 12:31
Delphi6
Разработчики РНР-люди, а они то и совершают ошибки
Автор: Delphi6
Дата сообщения: 09.09.2006 13:45
Brodyaga
Согласен, но они не простые программисты, они почти БОГИ!

Вот что я заметил сегодня в оф. документации

Цитата:
int preg_match_all ( string pattern, string subject, array &matches [, int flags [, int offset]] )

Ищет в строке subject все совпадения с шаблоном pattern и помещает результат в массив matches в порядке, определяемом комбинацией флагов flags.

После нахождения первого соответствия последующие поиски будут осуществляться не с начала строки, а от конца последнего найденного вхождения.

Есть идея написать свой preg_match_all на базе preg_match хотя это должен делать не я а профессионал, ибо я тоже могу допустить ошибку Как что-то проясниться обязательно скину
Автор: DLans
Дата сообщения: 09.09.2006 14:16
Думаю вопрос сюда.

В общем, я кое-что понял в регулярных выражениях..
Кроме этого.

Например BB тег URL реализуется так:

Код:
$emsg = preg_replace("#\[url=(.*?)\](.*?)\[/url\]#si", "<a class=\"links\" target=\"_blank\" href=\"\\1\">\\2</a>", $emsg);
$emsg = preg_replace("#\[url\](.*?)\[/url\]#si", "<a class=\"links\" target=\"_blank\" href=\"\\1\">\\1</a>", $emsg);
Автор: Delphi6
Дата сообщения: 09.09.2006 16:44
DLans
Два слеша а за ним цифра означает индекс елемента в "совпадениях", подробно написано вот здесь, да еще и на русском
http://uk.php.net/manual/ru/function.preg-replace.php
Удачи
Автор: KADABRA
Дата сообщения: 09.09.2006 16:44
Delphi6

Цитата:
после того как найдутся все таблицы, вручную рекурсивно искать таблицы в уже полученных таблицах

Не понял, зачем?
Предположим что таблицы не будут иметь вложенность больше 15 - тогда разбирается регекспом!

Цитата:
Хотя я не могу скрыть недовольство и такой большой промах со стороны рег. выражений!

Регулярные выражения отлично с этим справляются.

Цитата:
Как можно было не учесть такого банального варианта?

Дык всё учтено. Регекспы (в перле ) с этим справляются )

Автор: Delphi6
Дата сообщения: 09.09.2006 16:51
KADABRA

Цитата:
Дык всё учтено. Регекспы (в перле ) с этим справляются )

А мне что сейчас язык программирования метянть? Я уже с РНР как одно целое


Цитата:
Предположим что таблицы не будут иметь вложенность больше 15 - тогда разбирается регекспом!

Что-то в этом варианте мне не нравиться, не могу точно сказать что, но интуиция подсказывает, дело здесь не чисто

По идее есть еще одно решение, надо воспользоваться ручным отступом, это самое подходящее, так как вариант с <td>val1<td>val2<td>val3<td> ничего кроме полу ручной обработки не поможет. Или я ошибаюсь делая такое заявление?
Автор: KADABRA
Дата сообщения: 09.09.2006 17:06
Delphi6

Цитата:
Что-то в этом варианте мне не нравиться, не могу точно сказать что, но интуиция подсказывает, дело здесь не чисто

Тот код что я дал отлично справляется с тем ХТМЛ что ты дал, да и с любык, в котором таблицы вложенности не более 3, ты его пробовал или нет?


Цитата:
А мне что сейчас язык программирования метянть? Я уже с РНР как одно целое

Ну иногда оказывается что выбран не оптимальный язык


Цитата:
По идее есть еще одно решение, надо воспользоваться ручным отступом, это самое подходящее, так как вариант с <td>val1<td>val2<td>val3<td> ничего кроме полу ручной обработки не поможет. Или я ошибаюсь делая такое заявление?

Всё можно сделать вручную. Но иногда лучше автоматизировать. И иногда можно автоматизировать то, то кажется невозможно
А на счёт
Цитата:
<td>val1<td>val2<td>val3<td>

Щас посмотрю..


Добавлено:
<td>val1<td>val2<td>val3<td>
Кстати, это не валидный xhtml.

Добавлено:
Щас ничего в голову не приходит...
Автор: DLans
Дата сообщения: 09.09.2006 17:25
Delphi6
спасибо!
Автор: Cheery
Дата сообщения: 09.09.2006 17:26
Delphi6
проблема с таблицами заключается в том, что preg_match начинает поиск с начала. и первые <table></table> попадают под маску.
Автор: Delphi6
Дата сообщения: 09.09.2006 17:43
Cheery
Вот именно попадают первая таблица (он же и минимальный с самого начала), а каждый последующий поиск происходит с места где заканчивается первая таблица. Вот и получается что внутренняя таблица исключается
Нужно наверно заюзать:

Цитата:
...После нахождения первого соответствия последующие поиски будут осуществляться не с начала строки, а от конца последнего найденного вхождения...
Автор: user128
Дата сообщения: 27.09.2006 19:01
Надо удалить все аттрибуты у всех тегов, кроме a, p, img.

Код: preg_replace("!<([a-z]+)[^>]*>!is", "<\\1>", $string);
Автор: Cheery
Дата сообщения: 27.09.2006 19:26
user128
("!<([^ap(img)]?)\s[^>]*>!
не проверял

ps: нет, не пашет.. подумаю, когда будет время

pps: вот
Код: preg_replace("/<([^ap(img)].*?)\s.*?>/is", "<\\1>", $string);
Автор: Terabyte
Дата сообщения: 02.10.2006 08:22
Помогите составить две регулярки: Для ввода мыла и ФИО (на англ).

Для мыла нашел:
preg_match("/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/",$email)
Но она пропускает мыла test@test.ru88 (т.е. цифры в домене верхнего уровня).

Для проверки ФИО вообще не понял, ошибку выдает:
preg_match("^[\-a-zA-Z_ ]+$",$name)

Спасибо.
Автор: Smle
Дата сообщения: 10.10.2006 13:30
Нужно запретить поиск меньше чем по 3м символам.
Знаю что .* означает здесь ноль и больше символов. Регулярные отношения изучаю;)

#$text =~ s/\n/<br>/sg;
#$text =~ s/\[b\]/<b>/sg;
#$text =~ s/\[\/b\]/<\/b>/sg;
$text =~ s/\[quote\]/Цитата:/sg;
$text =~ s/\[\/quote\]//sg;

$text =~ s/\[url\](.*?)\[\/url\]//sg;
$text =~ s/\[url\=(.*?)\](.*?)\[\/url\]//sg;

$text =~ s/\[img\](.*?)\[\/img\]//sg;
$text =~ s/\[img\=(.*?)\](.*?)\[\/img\]//sg;

если вместо (.*?) вставлю {3,} то ничего не меняется. Также продолжает искать по одной и по двум буквам (
Автор: Delphi6
Дата сообщения: 22.10.2006 18:17
Доброе время суток,
Как можно выбрать не просто все урлы в HTML странице а те которые не начинаются на http://, другими словами локальные.

Код: preg_match_all("#\s(?:href|src|url)=(?:[\"\'])?(.*?)(?:[\"\'])?(?:[\s\>])#i", $buffer, $matches);
Автор: Delphi6
Дата сообщения: 22.11.2006 16:54
Почему данное рег. выражение не отлавливает все параметры?

Код: <?php $string = '<table border="0" cellpadding = "0" cellspacing=0 style="border-collapse: collapse">';
if (preg_match_all('#\s+([^=\s]+)\s*=\s*(?(?=") "([^"]+)" | ([^\s]+))#is', $string, $matches)) {
print_r($matches);
}
?>
Автор: Brodyaga
Дата сообщения: 22.11.2006 16:56
Может такое подойдет? от Perl:
/([-_\w:]+) \s* ( = \s* (?> ("[^"\"\=]*" | '[^'\'\=]*' | \S*) ) )?/xs
Автор: sTa1kEr
Дата сообщения: 22.11.2006 17:41
Delphi6
Или такое на PHP:
preg_match_all('/([a-z_\-]+)\s*=\s*(\'[^\']*\'|"[^"]*"|[a-z_\-0-9]+)/i', $string, $matches);
Автор: Delphi6
Дата сообщения: 22.11.2006 21:31
Brodyaga
sTa1kEr
Супер, как то не сообразил что можно вставить все в OR Сейчас уже не могу сообразить насколько код подойдет но на 90% уверен что это то что нужно
Спасибо
Автор: Delphi6
Дата сообщения: 22.11.2006 23:38
Brodyaga
sTa1kEr
ВСЕ УДАЛИЛ ТАК КАК НАШЕЛ РЕШЕНИЕ

Код: $string = '<table border=\'0\' cellpadding = "0" cellspacing=0 style= "border-collapse: collapse">';
if (preg_match_all('#\s+([^=\s]+)\s*=\s*(?(?="|\') (?:"|\')([^"\']+)(?:"|\') | ([^\s]+))#isx', $string, $matches)) {
print_r($matches);
}
Автор: sTa1kEr
Дата сообщения: 23.11.2006 10:04
Delphi6

Цитата:
Вот только вопрос как бы результат засунуть в 2 подмаски на не в 3?

Просто добавь еще одни скобки:

Код:
$string = '<table border=\'0\' cellpadding = "0" cellspacing=0 style= "border-collapse: collapse">';
if (preg_match_all('#\s+([^=\s]+)\s*=\s*((?(?="|\') (?:"|\')([^"\']+)(?:"|\') | ([^\s]+)))#isx', $string, $matches)) {
print_r($matches);
}

Страницы: 12345678910111213141516171819202122232425262728293031323334

Предыдущая тема: Xitami Web Server + PHP+ zend optimizer


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.