Regex question

Any questions involving matching text strings to patterns - the pattern is called a "regular expression."

Moderator: General Moderators

Post Reply
Trinsie
Forum Newbie
Posts: 2
Joined: Wed Nov 29, 2006 10:36 pm

Regex question

Post 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:

\{(.+?)\}
User avatar
GeertDD
Forum Contributor
Posts: 274
Joined: Sun Oct 22, 2006 1:47 am
Location: Belgium

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

)
User avatar
sweatje
Forum Contributor
Posts: 277
Joined: Wed Jun 29, 2005 10:04 pm
Location: Iowa, USA

Post 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
Trinsie
Forum Newbie
Posts: 2
Joined: Wed Nov 29, 2006 10:36 pm

Post 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!!


.
User avatar
sweatje
Forum Contributor
Posts: 277
Joined: Wed Jun 29, 2005 10:04 pm
Location: Iowa, USA

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

}
Post Reply