Помогите составить регулярное выражение?

Altex

Новичок
Помогите составить регулярное выражение?

PHP:
<?php


$text =<<<HTMLTEXT
<table>
<tr>
<td>!!!</td><td>111</td><td>222</td><td>333</td>
<td>444</td><td>555</td><td>7</td><td>88</td>
</tr>
<tr>
<td>aaa</td><td>bbb</td><td>ccc</td><td>ddd</td>
<td>eee</td><td>fff</td><td>ggg</td><td>ss</td>
</tr>
<tr>
<td>123</td><td>321</td><td>!!!</td><td>123</td>
<td>123</td><td>123</td><td>123</td><td>123</td>
</tr>
<tr>
<td>hdfg</td><td>hdfgh</td><td>dfghd</td><td>!!!</td>
<td>dfgh</td><td>dfghdf</td><td>dfgh</td><td>dfghdh</td>
</tr>
</table>

HTMLTEXT;

$REG = "~<tr>(.*!!!.*)</tr>~isU";

preg_match_all($REG,$text,$m);

echo "<pre>";
print_r($m);


?>
Здравствуйте, помогите, пожалуйста, с регекспом. Есть HTML таблица. В некоторых ячейках этой даблицы есть определённое сочетание символов (в примере выше - !!!). Нужно с помощью регов выделить массив со строками HTML талблицы (<tr>.....</tr>), в которых есть эта ячейка.

Попробывал решить задачу как указано выше - "~<tr>(.*!!!.*)</tr>~isU" . Но эта запись захватывает ненужные строки HTML талблицы.

В примере получается
Код:
    [1] => Array
        (
            [0] => 

<td>!!!</td><td>111</td><td>222</td><td>333</td>
<td>444</td><td>555</td><td>7</td><td>88</td>

            [1] => 
--------- вот эта часть лишняя -------
<td>aaa</td><td>bbb</td><td>ccc</td><td>ddd</td>

<td>eee</td><td>fff</td><td>ggg</td><td>ss</td>
</tr>
<tr>
--------- /вот эта часть лишняя -------
<td>123</td><td>321</td><td>!!!</td><td>123</td>
<td>123</td><td>123</td><td>123</td><td>123</td>

            [2] => 
<td>hdfg</td><td>hdfgh</td><td>dfghd</td><td>!!!</td>
<td>dfgh</td><td>dfghdf</td><td>dfgh</td><td>dfghdh</td>

        )
а нужно чтобы получилось
Код:
    [1] => Array
        (
            [0] => 

<td>!!!</td><td>111</td><td>222</td><td>333</td>
<td>444</td><td>555</td><td>7</td><td>88</td>

            [1] => 
<td>123</td><td>321</td><td>!!!</td><td>123</td>
<td>123</td><td>123</td><td>123</td><td>123</td>

            [2] => 
<td>hdfg</td><td>hdfgh</td><td>dfghd</td><td>!!!</td>
<td>dfgh</td><td>dfghdf</td><td>dfgh</td><td>dfghdh</td>

        )
Спасибо.
 

sakon

П..и.н..ок
"~<tr>(.*!!!.*)</tr>~isU"

"/<tr>(.*?)!!!(.*?)<\/tr>/is";
Найди одно важное отличие.

Хотя сорри. Неправильно понял.

-~{}~ 07.02.05 18:49:

Вот, что у меня получилось (незнаю на сколько тебе это подойдет).
1. Регом разбил текст на строки
2. Проверил наличие в строках "!!!"
3. Вывел строки в которых есть "!!!"
Конечно несколько через Ж..., но работает
PHP:
$REG = "/<tr>(.*?)<\/tr>/is";
preg_match_all($REG,$text,$m);
foreach ($m[1] as $stroka)
{
	if (strstr($stroka, "!!!")){
		echo $stroka."<BR>";
		}
}
 

texrdcom

Новичок
<?php



$text =<<<HTMLTEXT
<table>
<tr>
<td>!!!</td><td>111</td><td>222</td><td>333</td>
<td>444</td><td>555</td><td>7</td><td>88</td>
</tr>
<tr>
<td>aaa</td><td>bbb</td><td>ccc</td><td>ddd</td>
<td>eee</td><td>fff</td><td>ggg</td><td>ss</td>
</tr>
<tr>
<td>123</td><td>321</td><td>!!!</td><td>123</td>
<td>123</td><td>123</td><td>123</td><td>123</td>
</tr>
<tr>
<td>hdfg</td><td>hdfgh</td><td>dfghd</td><td>!!!</td>
<td>dfgh</td><td>dfghdf</td><td>dfgh</td><td>dfghdh</td>
</tr>
</table>

HTMLTEXT;

$REG = "~<tr>(.*!!!.*)</tr>~isU";

preg_match("#(<[\s]*tr[\s]*>[\w\W]*?!!![\w\W]*?</tr>)#i",$text,$m);

echo "<pre>";
print_r($m);


?>
Вроде так! если я правильно понял что ты хотел.

-~{}~ 07.02.05 23:09:

почемуто добавился лишний пробел перед скобкой
)
убери его
preg_match("#(<[\s]*tr[\s]*>[\w\W]*?!!![\w\W]*?</tr>)#i",$text,$m);
 

alexhemp

Новичок
вообще-то '!' - спец символ в PRCE вроде.

попробуйте на всякий случай применить preg_quote
 

texrdcom

Новичок
Не какой не спец символ - !- просто товарищ sakon прав вот так работает как ты хочешь.
<?php
$text =<<<HTMLTEXT
<table>
<tr>
<td>!!!</td><td>qqq</td><td>222</td><td>333</td>
<td>444</td><td>555</td><td>7</td><td>88</td>
</tr>
<tr>
<td>aaa</td><td>bbb</td><td>ccc</td><td>ddd</td>
<td>eee</td><td>fff</td><td>ggg</td><td>ss</td>
</tr>
<tr>
<td>www</td><td>321</td><td>!!!</td><td>123</td>
<td>123</td><td>123</td><td>123</td><td>123</td>
</tr>
<tr>
<td>ggg</td><td>hdfgh</td><td>dfghd</td><td>!!!</td>
<td>dfgh</td><td>dfghdf</td><td>dfgh</td><td>dfghdh</td>
</tr>
</table>

HTMLTEXT;

$REG = "~<tr>(.*!!!.*)</tr>~isU";

$kol=preg_match_all("#(<tr>[\w\W]+?</tr>)#i",$text,$m);
echo "<pre>";
for ($i=0; $i<$kol; $i++)
{
$tes=$m[0][$i];
$poisk=preg_match("#[\w\W]*?!!![\w\W]*#i", $tes);
if($poisk>0)
{
echo $tes;
echo '<hr>';
}
}
?>
на выхлопе:
<pre><tr>
<td>!!!</td><td>qqq</td><td>222</td><td>333</td>
<td>444</td><td>555</td><td>7</td><td>88</td>
</tr><hr><tr>
<td>www</td><td>321</td><td>!!!</td><td>123</td>
<td>123</td><td>123</td><td>123</td><td>123</td>
</tr><hr><tr>
<td>ggg</td><td>hdfgh</td><td>dfghd</td><td>!!!</td>
<td>dfgh</td><td>dfghdf</td><td>dfgh</td><td>dfghdh</td>
</tr><hr>

-~{}~ 08.02.05 00:14:

хотелось бы увидеть префесиональное решения если кто конечно заглянет в данную тему как одним выражениям
можно сделать данную задачу и вообще можно ли её так сделать?
 

Altex

Новичок
Спасибо! Действительно это вполне приемлемый, а главное рабочий вариант - сначала всю таблицу разбить на табличные HTML строки, а затем выбрать нужные. Спасибо!.

Но всё же очень хочется увидеть решение с помощью одного только регулярного выражения. Почему то мне кажется, что так сделать можно.

-~{}~ 08.02.05 09:27:

Хм. Вообще у меня тут такое рассуждение пришло в голову. По сути для решения подобных задач можно обозначить левую и правую границы ('/<tr>(.*)<\/tr>/'), а внутри проверить сразу 2 условия. Вот если бы нужно было проверить, чтобы совпадало хотя бы одно условие, то нужно было бы использовать (expr|expr), а тут нужно сразу несколько проверить условий, как один из возможных вариантов конечно. Тоесть необхдимо совпаления со следующими условиями: 1 - чтобы встретилось искомое сочетание символов (!!!), 2 - чтобы не встретились границы (<tr>, </tr>)

Если бы был какой-нибудь оператор, типа "|" только наоборот - "&", то можно было бы решить так '/<tr>(!!!&(?!<tr>)&(?!<\/tr>))<\/tr>/'.
 

Altex

Новичок
Тут как раз вот в чем проблема, ---- (?!<\/tr> )!!! ----- означает, что закрывающий тэк не должен стоять непосредственно перед искомыми символами (!!!). А это всегда выполняется. И этот тэг спокойно входит в первую (.*)
 

Altex

Новичок
Вообще вот это тоже не работает, но очень показалось дожно бы
~<tr>(?!.*<tr>.*)!!!(.*?)</tr>~is

-~{}~ 08.02.05 11:43:

Автор оригинала: sakon
Немного не так - не перед "!!!" а после "<tr>".
Если я правильно понимаю, после <tr> идет как раз .* а уже потом ?!</tr> и сразу после этого !!!. Ну вобщем всё равно вопрос открыт :)
 

Altex

Новичок
Я пробую сначала, а уже потом пишу.

-~{}~ 08.02.05 13:22:

Скажи точно, какой вариант должен работать, на твой взгляд? Я ещё раз попробывал последние варианты.
 

texrdcom

Новичок
вообще я думаю так что нельзя сделать одним выражениям надо делать двумя - не всегда можно в одном выражения описать все что хочеш, и во вторых если напишеш одно выражения и оно будет сложное и большое то оно будет работать дольше чем два коротких!!!! вот от этого и оталкивайся :)
 
Сверху