Page 1 of 1
Search Lists which are in a table cell only
Posted: Tue Sep 24, 2013 7:48 am
by radiks
Hi All,
I have the following problem. I want to insert in a table only these lists which are in a table cell. These which are not in a table let's keep it that way
Here is my code:
$replaceList = '$1$2<table class="listTbl"><tr><td>$3</td></tr></table>$4$5';
$html = preg_replace('/(<td>){1}(.*?)(<ul>[\s\S]*?<\/ul>)(.*?)(<\/td>){1}/smi', $replaceList, $html);
If there is following:
<table>
<tr>
<td>Test</td>
</tr>
<tr>
<td>
Text here
<ul>
<li>Test1</li>
<li>Test2</li>
</ul>
Text
</td>
</tr>
To become:
<table>
<tr>
<td>Test</td>
</tr>
<tr>
<td>
Text here
<table class="listTbl"><tr><td>
<ul>
<li>Test1</li>
<li>Test2</li>
</ul>
</td></tr></table>
Text
</td>
</tr>
Thanks!
Re: Search Lists which are in a table cell only
Posted: Tue Sep 24, 2013 9:00 am
by radiks
I forgot to mention that my code works, but where I have lists between 2 tables insert and them in the table. May be because I have (.*?)
How could I do to search only those lists that are in a table?
Thanks!
Re: Search Lists which are in a table cell only
Posted: Tue Sep 24, 2013 1:14 pm
by ragax
I think you're going to need
preg_replace_callback.
You can then (break)(your)(match)(into)(capture)(chunk) and reassemble everything however you want.
The easiest example of this is actually not on the preg_replace_callback page but on the
anonymous function page.
Re: Search Lists which are in a table cell only
Posted: Tue Sep 24, 2013 2:29 pm
by radiks
Thanks for the answer ragax!
I have a problem with the pattern. No matter which function use.
I want to find all lists that are in а table. But those who are outside the table do not care. As and my pattern includes in the matches and lists that are out of table, but they are between 2 tables because in it there is (.*?). i.e. looking for anything between <td> and </td>.
Re: Search Lists which are in a table cell only
Posted: Tue Sep 24, 2013 8:03 pm
by ragax
Hi radiks,
To do this in regex, you need to use
regex lookahead and lookbehind.
To give you an example, this pattern will match from an opening <td> to the next <li> that occurs before the closing </td>.
After that, you can start adding your capture groups etc.
(?s)<td>(?!.*?</td>.*?<li>).*?<li>
It says "match a <td>, then, { if at this point we cannot match stuff followed by a closing </td>, more stuff and a <li> }, match stuff then the <li>.
That should give you a place to start.

Re: Search Lists which are in a table cell only
Posted: Wed Sep 25, 2013 6:14 am
by radiks
Hi ragax,
Thanks for your answer!

Almost happened but when I have a table without lists in it and after the table list that is not in a table then and this list enters in matches. Why? Where I'm wrong?
Here is my code:
Code: Select all
$html = preg_replace_callback('/(<td>)+(?!<td>.*?<\/table>.*?<ul>).*?(<ul>.*?<\/ul>)+.*?(<\/td>)+/smi', 'replaceCallbackFn', $html);
function replaceCallbackFn($matches)
{
if(is_array($matches) && !empty($matches))
{
return preg_replace('/(<td>)(.*?)(<ul>.*?<\/ul>)(.*?)(<\/td>)/smi','$1$2<table class="listTbl" style="border:1px solid red; color:green;"><tr><td>$3</td></tr></table>$4$5',$matches[0]);
}
}
Re: Search Lists which are in a table cell only
Posted: Wed Sep 25, 2013 6:52 am
by radiks
I feel powerless!
I found another case where my code does not work.
Here are two cases that I noticed:
Case 1:
<table width="100%" border=1>
<tr>
<td>
Text here!
</td>
</tr>
</table>
<ul>
<li>List Text 1</li>
<li>List Text 2</li>
</ul>
Case 2:
<table>
<tr>
<td>
<table>
<tr>
<td>
<ul><li>Test1</li><li>Test2</li></ul>
</td>
</tr>
</table>
<ul>
<li>List Text 1</li>
<li>List Text 2</li>
</ul>
</td>
</tr>
</table>
Re: Search Lists which are in a table cell only
Posted: Wed Sep 25, 2013 4:17 pm
by ragax
Hi radiks,
I don't have time to look in detail today, but at first glance it looks to me that you may not be using preg_replace_callback properly. It looks like the function you are calling uses a preg_match. But the idea for the function you call is that you pass it the array of matches, then that it returns something with it: for instance return "some prefix".$matches[1]."some suffix";
Please have a look at Example #1 on this page, and particularly at what the callback function does (just a strtoupper), the syntax might be a lot simpler than you are thinking.
http://www.php.net/manual/en/functions.anonymous.php
That being said I did not read your code in detail and maybe there is a reason for a preg_match in the callback function, but that would be rare.
Re: Search Lists which are in a table cell only
Posted: Wed Sep 25, 2013 4:43 pm
by ragax
Hi again. Thought I'd take a quick close look. This code addresses your original question (please run it). Simple replace so no need for a callback.
Code: Select all
$string = '<table>
<tr>
<td>Test</td>
</tr>
<tr>
<td>
Text here
<ul>
<li>Test1</li>
<li>Test2</li>
</ul>
Text
</td>
</tr>
';
$regex = '~(?s)<td>(?!.*?</td>.*?<ul>).*?\K<ul>.*?</ul>~';
$replace = '<table class="listTbl"><tr><td>\0</td></tr></table>';
$newstring = preg_replace($regex,$replace,$string);
echo htmlentities($newstring).'<br />';
Does that take care of your problem?