Reputation: 2992
I'm trying to do a PHP regular expression but i can't find the right way ...
Imagine I have this string: "hello, my {{name is Peter}} and {{I want to eat chocolate}}"
I want to take the parts between {{ and }}
But if I use preg_match("/\{\{(.*)?\}\}/", $string)
it returns me jut one string "{{name is Peter}} and {{I want to eat chocolate}}"
How can I tell to take the first coincidences of }} ?
Thank you
Upvotes: 10
Views: 9151
Reputation: 2131
This worked for me.
$subject = 'Hello {{name}}, here is an email {{email}} and phone # {{phone}}';
$replace = array(
'{{name}}' => 'Bob',
'{{email}}' => '[email protected]',
'{{phone}}' => '5155554455'
);
$output = preg_replace_callback('{{{?(#[a-z]+ )?[a-z]+.[a-z]*}?}}', function($match) use ($replace) {
if(isset($replace[$match[0]])){
return ($replace[$match[0]]);
} else {
return($match[0]);
}
}, $subject);
var_dump($output);
Upvotes: 0
Reputation: 132051
The PCRE functions a greedy by default. That means, that the engine always tries to match as much characters as possible. The solution is simple: Just tell him to act non-greedy with the U
modifier
/{{(.+)}}/U
http://php.net/reference.pcre.pattern.modifiers
Upvotes: 8
Reputation: 8560
EDITED
As non-greedy matching seems to be faster than negated one (see here), I change my answer too. Thought it was the other way round...
preg_match("/\{\{(.*?)\}\}/", $string)
You might want to use preg_match_all
to get all matches
Upvotes: 0
Reputation: 92792
You want "ungreedy matching": preg_match("/{{(.*?)?}}/", $string)
.
Note the first question mark - a regex, by default, is "greedy": given multiple ways to match, it matches as much text as it possibly can. Adding the question mark will make it ungreedy, so if there are multiple ways to match, it will match as few characters as it possibly can.
Upvotes: 2
Reputation: 25593
Use
"/{{(.*?)}}/"
The expression ".*"
is greedy, taking as many characters as possible.
If you use ".*?"
is takes as little characters as possible, that is it stops at the first set of closing brackets.
Upvotes: 31