Page 1 of 1
Regex question
Posted: Wed Nov 29, 2006 10:38 pm
by Trinsie
can someone figure out how to get regex working for a code like
Code:
{test{hello},{world}}
this type to show 3 results
{test,{hello},{world}} -- no change
{hello} -- only the hello
{world} -- only the world
current regex code i came up with only catches one match {...text...} and cannot include { and } within the {...text...}
Code:
\{(.+?)\}
Posted: Thu Nov 30, 2006 1:02 pm
by GeertDD
You gave us two different strings as the starting point. Which one to use?
{test{hello},{world}}
{test,{hello},{world}}
Starting from the second string, I came up with the regex below.
Code: Select all
preg_match_all('/(?<=,)(?:{.+?})/', '{test,{hello},{world}}', $matches);
// contents of $matches:
Array
(
[0] => Array
(
[0] => {hello}
[1] => {world}
)
)
Posted: Thu Nov 30, 2006 4:41 pm
by sweatje
The trouble is a single regex can only match (consume) the the data once, so you could write a pattern to get all of the individual ones:
'~{[^{}]*}~ms'
or you could write a recursive pattern to match until you have a complete sets of open and closing curly braces
'~(({[^{}]*})|{(?:[^{}]*(?2))*})~ms'
but you can't get both at the same time
Posted: Thu Nov 30, 2006 7:28 pm
by Trinsie
GeertDD wrote:You gave us two different strings as the starting point. Which one to use?
{test{hello},{world}}
{test,{hello},{world}}
Starting from the second string, I came up with the regex below.
Code: Select all
preg_match_all('/(?<=,)(?:{.+?})/', '{test,{hello},{world}}', $matches);
// contents of $matches:
Array
(
[0] => Array
(
[0] => {hello}
[1] => {world}
)
)
2nd one is correct, you got the part I'm stuck on but this might be more complicated than what I was expecting. This is for my template system I'm working on, I don't think I would be able to figure out how to translate {hello} and {world} before {test, XXX, YYY}
Like say test was a function and XXX and YYY were values used in the function the XXX and YYY has to be defined before the test.
Example:
define("hello", "Power Puff");
define("world"," Girls");
function test($value1, #value2){
echo $value1 . $value2;
}
in template file when you do
I like watching the
{test,{hello},{world}}! Specially like Bubbles!!
it should result in
I like watching the
Power Puff Girls! Specially like Bubbles!!
.
Posted: Sat Dec 02, 2006 12:48 pm
by sweatje
I think this is what you are looking for:
Code: Select all
function template($match) {
$repl = array('hello' => 'one'
,'world' => 'two'
,'test,one,two' => 'Power Puff Girls');
$value = trim($match[0],'{}');
if (array_key_exists($value,$repl)) {
return $repl[$value];
}
return $match[0];
}
class MiscTestCase extends UnitTestCase {
function testMiniTemplateAlgorythm() {
$tpl = 'I like watching the {test,{hello},{world}}! Specially like Bubbles!!';
$desired = 'I like watching the Power Puff Girls! Specially like Bubbles!!';
$last = $tpl;
while ($last != $cur = preg_replace_callback('~{[^{}]*}~ims', 'template', $last)) {
$last = $cur;
}
$this->assertEqual($desired, $last);
}
}