regex backreferences in PHP (preg_replace)

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Bubi
Forum Newbie
Posts: 5
Joined: Wed Mar 28, 2012 8:36 pm

regex backreferences in PHP (preg_replace)

Post by Bubi »

A little backstory: I am writing a plugin for a bb forum (mybb to be exact) which parses the posted message and replaces some BB code
sample synthax is:

Code: Select all

[gplay=first_argument]second_argument[/gplay]
The regex code itself works (adapted it from a sample plugin), but I want to have the returned regex string
in a variable, which I can check if it was set.
Here's the code:

Code: Select all

<?php function bbcode_input($first, $second)
{
  $return = "Length: " . strlen(strval($second)) . " - " . $second; // length is always 2, but does not output anything if printed
  $return .= var_dump($second); //always tells me it's 2 chars long and contains "$2"
  return $return;
}
function gplay_infobox_run($message)
{
  $pattern = array("#\[gplay=(?:"|\"|')?(.*?)[\"']?(?:"|\"|')?\](.*?)\[\/gplay\](\r\n?|\n?)#si", "#\[gplay\](.*?)\[\/gplay\](\r\n?|\n?)#si");
  $replace = bbcode_input("$1", "$2"); // there it is <----
  while(preg_match_all($pattern[0], $message, $hello) or preg_match_all($pattern[1], $message, $hello))
  {
    $message = preg_replace($pattern, $replace, $message);
  }
  return $message;
}
?>
Example:

Code: Select all

[gplay]com.google.android.keep[/gplay]
Just one match, so $second is not returned, and $first is a string containing "com.google.android.keep"
Now I check if $second is actually "existing"

Code: Select all

<?php
if($second) 
...or...
if(empty($second)) 
...or...
if(isset($second)) 
?>
it doesn't work

so I did a var_dump. It tells me it always contains the string "$2"

So I cannot simply check:

Code: Select all

<?php
if($second=="$2") 
...
?>
because it will always pass.
Now if I print out the variable $second I get an empty string returned (because it gets replaced by the regex)

Code: Select all

[gplay=com.google.android.keep][/gplay]
Same as above

Code: Select all

[gplay=horizontal]com.google.android.keep[/gplay]
Practically the same...
If I print out the variable $second I get "com.google.android.keep" returned (because it also gets replaced by the regex)

How do I solve this tricky situation?
I cannot simply do a search and replace, because I need to load the theme (horizontal in the above example),
than vary the output, like placing a different div element which is bigger/smaller/wider/thinner/etc
and pass the other variable to a different script to load some external data

I know, it's a pretty wall of text, but I tried to be as exact as possible
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: regex backreferences in PHP (preg_replace)

Post by Weirdan »

Quick question: do you realize that actual matching/replacement occurs only when you call preg_replace and not when you define the pattern? From your explanation it appears you're expecting bbcode_input() to receive results of matching, however you're calling it before matching is done.

You might want to look into preg_replace_callback if my understanding is correct.
Bubi
Forum Newbie
Posts: 5
Joined: Wed Mar 28, 2012 8:36 pm

Re: regex backreferences in PHP (preg_replace)

Post by Bubi »

The first time I got stuck for so long, but you solved it in a matter of minutes!
Seriously, thank you very much!

For anyone who's interested, here is the function:

Code: Select all

function bbcode_input($input)
{
  if(!empty($input[1]))
  {
    if(empty($input[2]))
    {
    $theme = "DEFAULT!";
    $appid = $input[1];
    }
    else
    {
    $theme = $input[1];
    $appid = $input[2];
    }
  }
  else
  {
    $appid = "notset";
    $theme = "notset";
  }
}
and the preg_replace modified to preg_replace_callback:

Code: Select all

$message = preg_replace_callback($pattern, bbcode_input, $message);
- Problem solved -
Post Reply