Reputation: 5867
I have following code:
$content = <<<HTML
<p>{wrapper btnlabel="AAA"}zzzzzzzzzzzzzzzzzzzz{/wrapper}</p>
<p>{wrapper btnlabel="Text"}</p>
<table>
<tbody>
<tr>
<th scope="row">123</th>
<td>1 123</td>
<td>12 123</td>
<td>3 123</td>
<td>1 123 123</td>
</tr>
<tr>
<th scope="row">123</th>
<td>2700 123.</td>
<td>1800 123.</td>
<td>1000 123.</td>
<td>300 123.</td>
</tr>
</tbody>
</table>
<p>{/wrapper}</p>
HTML;
preg_match_all('#(?>{wrapper btnlabel=(?>"|")(.+)(?>"|")})(.*){/wrapper}#', $content, $matches);
var_dump($matches);
pattern doesn't match to second {wrapper...
. I think its because it split into multiple lines. But when i try s
modifier it match whole content from first {wrapper
until last {/wrapper}
in one. Replacement of \n
to ''
didn't help. So i'm confused. Maybe i miss something ?
https://ideone.com/ZMpSJ7 - here is the same test code
Upvotes: 4
Views: 847
Reputation: 627082
Just as I mentioned in the comments, you should be very careful with greedy patterns, only use them when you need to obtain the largest substring possible including subblocks. In other cases, when you need individual substrings, use lazy matching.
Here is a fixed regex:
(?>{wrapper btnlabel=(?>"|")(.+?)(?>"|")})(.*?){\/wrapper}
Sample code:
$re = "/(?>{wrapper btnlabel=(?>\"|")(.+?)(?>\"|")})(.*?){\\/wrapper}/s";
$str = "<p>{wrapper btnlabel="AAA"}zzzzzzzzzzzzzzzzzzzz{/wrapper}</p>\n\n<p>{wrapper btnlabel="Text"}</p>\n\n<table>\n<tbody>\n<tr>\n<th scope=\"row\">123</th>\n<td>1 123</td>\n<td>12 123</td>\n<td>3 123</td>\n<td>1 123 123</td>\n</tr>\n<tr>\n<th scope=\"row\">123</th>\n<td>2700 123.</td>\n<td>1800 123.</td>\n<td>1000 123.</td>\n<td>300 123.</td>\n</tr>\n</tbody>\n</table>\n\n<p>{/wrapper}</p>";
preg_match_all($re, $str, $matches);
Upvotes: 1