tags:

views:

60

answers:

3

I have a question about preg_replace() function. I'm using it with 'e' modifier. Here is code snippet:

$batchId = 2345;
$code = preg_replace("/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\@\^]{0,2}/e",
                     'translate_indicator(\'$0\', {$batchId})', $code);

I want to have access to $batchId variable inside translate_indicator($code, $batch=false) function. The above exapmle, unfortunately, doesn't work correctly: $batch is invisible(var_dump() result is bool(false)) within translate_indicator().

Probably, I have syntax mistakes in replacement code. Or, maybe, it's impossible to pass variables with preg_replace()?

Update for the first two answers.

Thank you for answers, but your advice didn't help. Besides I've already tried double qoutes instead of single qoutes. I've just simplified code to test possibility of passing parameter to the function:

$code = preg_replace("/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\@\^]{0,2}/e",
                     "translate_indicator('$0', 12)", $code);

Also I've removed default value for the $batch within translate_indicator(). Result:

Warning: Missing argument 2 for translate_indicator()

So I think it's impossible to pass parameter using this approach.:(

+1  A: 

try this instead

$batchId = 2345;
$code = preg_replace("/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\@\^]{0,2}/e",
                     "translate_indicator('$0', {$batchId})", $code);

singly-quoted strings aren't expanded (i.e. $batchId won't be subsituted).

Michael Krelin - hacker
+1  A: 

Use "translate_indicator('\$0', $batchId)" instead of 'translate_indicator(\'$0\', {$batchId})'.

watain
Btw I tried your `preg_replace()` code with `translate_indicator($a,$b)` as dummy function (`var_dump`'ing the arguments) and everything worked fine. What php version are you using?
watain
I've found preg_replace_callback() more appropriate for me. But thank's a lot for your comment. My update for question was wrong, because I've just mentioned, that I didn't put '\' before dollar sign, as you wrote. So I got '$0' instead of '\$0'. I didn't pay attention for this. Taht's why I've got warning.
Alex
Alright, I was just going to suggest you to use preg_replace_callback(). It's a more secure solution because you won't have problems with escaping string literals inside the matched strings, like `'` or `"`. I guess it's more performant, too.
watain
+1  A: 
$batchId = 2345;
$code = 'AA1#';
$code = preg_replace(
  "/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\@\^]{0,2}/e",
  "translate_indicator('\$0', $batchId)", /* if $batchId can be a string use 'batchId' */
  $code);

function translate_indicator($s, $batchId) {
  echo "translate_indicator($s, $batchId) invoked\n";
}

prints translate_indicator(AA1#, 2345) invoked.
You can also use preg_replace_callback and a class/an object

class Foo {
  public $batchId = 2345;
  public function translate_indicator($m) {
    echo "batchId=$this->batchId . $m[0]\n";
  }
}

$code = 'AA1#';
$foo = new Foo;
$code = preg_replace_callback(
  '/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\@\^]{0,2}/',
  array($foo, 'translate_indicator'),
  $code
);

As of php 5.3. you can also use an anonymous function + closure to "pass" the additional parameter.

$code = 'AA1#';
$batchId = 2345;
$code = preg_replace_callback(
  '/[A-Za-z]{2,4}[\d\_]{1,5}[\.YRCc]{0,4}[\#\&\@\^]{0,2}/',
  function($m) use ($batchId) {
    echo "batchid=$batchId . code=$m[0]\n";
  },
  $code
);
VolkerK
Thank you for comprehensive answer. It works great!!
Alex