Emphram Stavanger
Emphram Stavanger

Reputation: 4214

Match, eval and replace BBCode style tags

So in my PHP code I have a string like so;

The quick brown {{fox($a);}} jumped over the lazy {{dog($b);}}.

Now it might sound weird, but I want to go through the string, and collect all the BBCode style tags.

Then I want to eval() all the functions which are inside the {{}}'s. So I'd eval fox($a); and dog($b);.

Both of these functions return a string. And I want to replace the respective tags with the respective results. So supposing fox() returns "vulpes vulpes" and dog() returns "canis lupus", my original string would look like this;

The quick brown vulpes vulpes jumped over the lazy canis lupus.

However, I am famously terrible with regular expressions, and I have no idea how to go about this.

Any advice would be welcome!

(And yes, I am aware of the dangers of happy-go-lucky eval()ing. However, these strings come strictly from the developers and no user will ever be able to eval anything.)

Upvotes: 2

Views: 185

Answers (2)

nickb
nickb

Reputation: 59699

If you want to do this with a regex, here's a solution that seemed to work for me:

function fox( $a) { return $a . 'fox!'; }
function dog( $b) { return $b . 'dog!'; }

$a = 'A'; $b = 'B';
$string = 'The quick brown {{fox($a);}} jumped over the lazy {{dog($b);}}.';
$regex  = '/{{([^}]+)+}}/e';
$result = preg_replace( $regex, '$1', $string);

The regex is pretty simple:

{{       // Match the opening two curly braces
([^}]+)+ // Match any character that is not a closing brace more than one time in a capturing group
}}       // Match the closing two curly braces

Of course, the /e modifier causes the replacement to be eval'd, producing this:

Output:

var_dump( $result);
// string(49) "The quick brown Afox! jumped over the lazy Bdog!."

Upvotes: 3

Sam Dufel
Sam Dufel

Reputation: 17598

If you're only inserting valid php into those tags - you can just do a

$string = '.....';

$string = '?>' . $string;
$string = str_replace('{{', '<?php echo ', $string);
$string = str_replace('}}', '?>', $string);

ob_start();
eval($string);
$string = ob_get_clean();

Upvotes: 1

Related Questions