MyBB Community Forums

Full Version: Regex to match the quote MyCode?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
As part of my MyAlerts plugin I'm trying to use a regular expression to match the quote MyCode. After having looked at the parser, I believe the following should work:

$pattern = "#\[quote=([\"']|"|)(.*?)(?:\\1)(.*?)(?:[\"']|")?\](.*?)\[/quote\](\r\n?|\n?)#esi";

It does indeed work, but looping through it to find all quotes within a post is taking a very long. I'm therefore wondering if I'm just missing something? Regex is by no means my forte so if somebody with a better grasp of the subject can help I'd be super grateful.
for my quote_notice plugin I use

//get message body
$message = $postdata->data['message'];
		
// Assign pattern value
$pattern = "#\[quote=([\"']|"|)(.*?)(?:\\1)(.*?)(?:[\"']|")?\](.*?)\[/quote\](\r\n?|\n?)#esi";

//try to find all the quoted contents
$nummatched = preg_match_all($pattern, $message, $matches);

//if we found matches
if($nummatched)
{
	//do stuff here
}

oops, we are using the same regex. it only pulls the first quote, nothing nested. it should return all quoted blocks from the same user, you just need to track that you have already "triggered" that user for notification
I kinda just realised I was using preg_match() instead of preg_match_all()... Oops. Thanks for the response pavemen.

I also just realised that regex isn't quite perfect either as I'm trying to grab the usernames only. You can have two types of quote:

[quote="me"]
...
[/quote]

[quote=me]
...
[/quote]

The username is then stored in different locations within the $match array for each quote type. That isn't all that much use to me as I need to know exactly where the username is.
Right, worked out a way round it. It's not exactly the best solution in the world but it seems to work:

$pattern = "#\[quote=([\"']|"|)(.*?)(?:\\1)(.*?)(?:[\"']|")?\](.*?)\[/quote\](\r\n?|\n?)#esi";

preg_match_all($pattern, $message, $match);
    
    $output = array_merge($match[2], $match[3]);


foreach($output as $key => $value) { 
    if($value == "") { 
        unset($output[$key]); 
    } 
} 

$new_array = array_values($output);
(2012-05-23, 06:56 PM)euantor Wrote: [ -> ]I kinda just realised I was using preg_match() instead of preg_match_all()... Oops. Thanks for the response pavemen.

I also just realised that regex isn't quite perfect either as I'm trying to grab the usernames only. You can have two types of quote:

[quote="me"]
...
[/quote]

[quote=me]
...
[/quote]

The username is then stored in different locations within the $match array for each quote type. That isn't all that much use to me as I need to know exactly where the username is.


But that should be handled by the extra pipe with nothing after it in the regex. (where I have placed the X below)

$pattern = "#\[quote=([\"']|"|X)(.*?)(?:\\1)(.*?)(?:[\"']|")?\](.*?)\[/quote\](\r\n?|\n?)#esi";
Doesn't seem like it was being for some reason. I was testing it by performing the match then dumping the array and it was definitely under a different array key.

Right, the above method works. To a point. It's okay if you use either of the two quote formats I posted above but if you use the MyBB system to create the quote (so that the dateline parameters etc are set) you start to have a problem in that the extra parameters are stored in the same array key. I can't currently think of a way round this at all. If anybody wants to see the code currently in use in order to try help, feel free to take a look: https://github.com/euantor/MyAlerts/blob...s.php#L293
strange, but merging the keys could cause a problem if you have one block with quotes and one without in the same post. due to edits or copy/paste or even manual quoting
Yeah, I think I might have to leave this till tomorrow when I can look at it with fresh eyes. Not sure if you saw the edit I added, but I noticed another problem with the current way I'm doing it. Definitely going to have to take a bit of a re-think on the technique.