I'am trying to get all {{product.smth}} with preg_match_all, but if i have few of this in one line i get wrong result.
Example:
$smth = '<name>{{product.name}}</name><getname>{{product.getName()}}</getname>';
$pattern = '/\{\{product\.(.*)\}\}/';
preg_match_all($pattern, $smth, $matches);
//returns '{{product.name}}</name><getname>{{product.getName()}}'
//instad of '{{product.name}}' and '{{product.getName()}}'
What iam doing wrong? Please help.
The problem is that repetition is greedy. Either make it ungreedy by using .*?
or better yet: disallow the }
character for the repetition:
$pattern = '/\{\{product\.([^}]*)\}\}/';
If you do want to allow single }
in that value (like {{product.some{thing}here}}
), the equivalent solution uses a negative lookahead:
$pattern = '/\{\{product\.((?:(?!\}\}).)*)\}\}/';
For every single character included in .*
it checks that that character doesn't mark the start of a }}
.
I think it'll work if you change .*
to .*?
this will make it lazy instead of greedy and it will try to match as little as possible - so, till the first occurance of }}
rather than the last.