tags:

views:

534

answers:

3

how to get string between [LOOP]...[/LOOP] i try this but not work

$gloop = preg_replace('/\[LOOP\]([^\[]*)\[\/LOOP\]/', '\\1', $var);

... string:

'<tr>
 [LOOP]<th scope="col">%Gdata_All%</th>[/LOOP]
</tr>'

but i would string in [LOOP]...[/LOOP]

+9  A: 

I would first like to say, are you creating your own template library? There are some mature ones around like Smarty which should be able to fill your requirements. This article by Jeff Atwood is also good read : "Don't Reinvent The Wheel, Unless You Plan on Learning More About Wheels"

If you want to roll your own solution then that is fine, here are some suggestions.

BBCode


This method relies on having the BBCode extension installed with PHP, it is native and does not rely on the regular expression engine (slow). This solution will probably be the fastest.

You can have the BBCode parser convert

[LOOP]<td><?php print $row->title; ?></td>[/LOOP]

into

<?php foreach($result as $row): ?><td><?php print $row->title; ?></td><?php endforeach; ?>

Look into the BBCode arguments to learn about passing variables into your [LOOP] syntax.

You can view some more examples on the bbcode_create method page.

Regular Expressions


They are a little bit slower, but are enabled by default on all PHP installations.

Credits to go Gumbo for this regular expression (You should up-vote him).

/\[LOOP]((?:[^[]+|\[(?=\/LOOP]))*)\[\/LOOP]/

You can then use it as follows.

if (preg_match('%\[LOOP\]((?:[^[]+|\[(?=/LOOP\]))*)\[/LOOP\]%i', $subject, $result)) {
    # Successful match
    # You can access the content using $result[1];
} else {
    # Match attempt failed
}

-Mathew

The Pixel Developer
With (.*?) it would still match "[LOOP]...[LOOP]...[/LOOP]". I think the OP had that part right: ([^\]]*). Assuming, of course, there can't be any brackets other than those in the tags. But that's a side issue; the real problem lay in trying to use preg_replace instead of preg_match. +1
Alan Moore
Ah yes, good point. The regex posted by Gumbo below solves this issue.
The Pixel Developer
+1  A: 

I would use this regular expression:

/\[LOOP]((?:[^[]+|\[(?=\/LOOP]))*)\[\/LOOP]/

It matches a sequence of any character other than [ ([^[]+) or the [ that is not followed by a /LOOP] (\[(?!\/LOOP]), (?!expr) is a negative look-ahead assertion) between a [LOOP] and [/LOOP]; the surrounding (?:expr) is a non-capturing grouping.

But it would certainly be better if you use a real parser to detect malformed code as The Pixel Developer already pointed out.

Gumbo
A: 
$code = preg_match('/(.*?)\[LOOP\](.*?)\[\/LOOP](.*?)/ims', $var, $result3);

how to get

echo $result[1];
echo $result[2];
echo $result[3];

but not working for echo $result[3];

monkey_boys
You need to look into preg_match_all, http://uk3.php.net/manual/en/function.preg-match-all.phpExamples are there too. Enjoy :)
The Pixel Developer
A non-greedy quantifier, as in (.*?), matches only as much as it has to until the next condition can be met. But your third (.*?) is the last thing in the regex; it doesn't have to match anything because there *is* no next condition.
Alan Moore