Yamile
Yamile

Reputation: 39

my regex work fine with preg_match, but fail with preg_replace, why?

I need remove any ROW "hidden" (display:none) from string:

$s = '<tr style="display:none"></tr><tr style="display:none"></tr><tr style="display:none"></tr><tr><td>A</td></tr><tr><td>B</td></tr><tr><td>A</td></tr><tr style="display:none"></tr><tr style="display:none"></tr>';

then I write my regex:

$x = '@<tr.*?style="display:none"></tr>@is';

I test my regex with:

preg_match($x, $s, $Q);
print_r($Q);

work fine!

Array
(
    [0] => <tr style="display:none"></tr>
)

and now I try delete any coincidence with my regex:

$Q = preg_replace($x, '', $s);
print_r($Q);

fail... :'(

why?

Upvotes: 0

Views: 27

Answers (1)

Alex Melnikov
Alex Melnikov

Reputation: 83

The issue is in the limit parameter of the preg_replace() function. By default it's -1, which makes it replacing all the found matches. And for your string all the matches are:

0-30    <tr style="display:none"></tr>
30-60   <tr style="display:none"></tr>
60-90   <tr style="display:none"></tr>
90-177  <tr><td>A</td></tr><tr><td>B</td></tr><tr><td>A</td></tr><tr style="display:none"></tr>
177-207 <tr style="display:none"></tr>

You may see it using preg_match_all() instead of preg_match(). The simple regex that avoids it should be:

$x = '@<tr[^>]*?style="display:none"></tr>@is';

But, as it's advised in the comments if your task is not that simple as the current question, it's not recommended to use regexes to parse HTML since it's to complicated.

P.S. Just in case a good resource to test regular expressions: https://regex101.com

Upvotes: 2

Related Questions