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);
}

}