3

Consider this text

$text = 'bla bla bla bla (=abc) bla bla bla bla (=var.var)';

There are 2 special values there (=abc) and (=var.var)

I need to replace them with values from this array:

$array['abc']='word1';
$array['var.var']='word2';

Basically inside the pattern is (=[a-z.]+) (chars a-z and dot).

Result i need: bla bla bla bla *word1* bla bla bla bla *word2* (without *)

I tried this with no luck

preg_replace('/\(=([a-z\.]+)\)/',"$array['\\1']",$text);

Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in D:\net\test\index.php on line 9

2 Answers 2

3

Since you the replacement string cannot be derived from the contents of the match (it involves external data in $array, you need to use preg_replace_callback.

This example assumes PHP 5.3 for anonymous functions, but you can do the same (in a slightly more cumbersome way) with create_function in any PHP version.

$text = 'bla bla bla bla (=abc) bla bla bla bla (=var.var)';
$array['abc']='word1';
$array['var.var']='word2';

$result = preg_replace_callback(
            '/\(=([a-z\.]+)\)/', 
            function($matches) use($array) { return $array[$matches[1]]; },
            $text);
Sign up to request clarification or add additional context in comments.

11 Comments

oh crap. first time i see use(arg) what's that O_O
@yes123: Re use($arg): the variable $arg (which must be in scope) becomes available to use inside the anonymous function as well -- otherwise you couldn't access it.
@jon: isn't that equal to global $arg; inside the func? Anyway i use php 5.3 so it's fine
@yes123: If $arg is already a global, it is. But use will also work if all this code were inside a function and $array was a local variable.
What do you mean? in this case wasn't this equal? function($matches) {global $array; return $array[$matches[1]]; }
|
2

The < PHP 5.3 solution :)

$text = 'bla bla bla bla (=abc) bla bla bla bla (=var.var)';

$text = preg_replace_callback('/\(=([\w.]+?)\)/', 'processMatches', $text);

function processMatches($matches) {
    $array = array();
    $array['abc']='word1';
    $array['var.var']='word2';
    return isset($array[$matches[1]]) ? $array[$matches[1]] : '';
}

var_dump($text); // string(43) "bla bla bla bla word1 bla bla bla bla word2"

CodePad.

2 Comments

This is a fully correct solution as well, but it's not ideal because you must either define $array inside processMatches, or make it a global. But +1 for the isset test.
@Jon Thanks, it is a shame the matches need to scoped to the callback.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.