Page 1 of 1

[Help] Match if not between [code] [/code]

Posted: Sat Sep 17, 2011 1:22 am
by KoBE
I've been trying desperately to find figure this out on my own. Here is the problem.
I am using regex to find: [posts=40]info goes here[/posts]
The regex pattern I'm using: $pattern = "#\[posts=(?:\"|')?(.*?)[\"']?(?:\"|')?\](.*?)\[\/posts\](\r\n?|\n?)#";

This all works find and dandy. But, what I'm trying to accomplish, is: If it is surrounded by code tags I don't want it to match.
For instance:

Code: Select all

 something could be here then [posts=40]info goes here[/posts]  could be there then I could end the tag 
I don't want to match the [posts] tag because it is enclosed inside the code tag. I hope I explained this well enough. Thanks to anyone that can help.

The string would look like

Code: Select all

[code] something could be here then [posts=40]info goes here[/posts]  could be there then I could end the tag 
[/code]

Re: [Help] Match if not between [code] [/code]

Posted: Sat Sep 17, 2011 5:34 am
by twinedev
This is (from what I know of regex) will not be accomplished with just regex. Pretty much would need to do one regex to match them all and put them in an array, Then do a second regex to find the ones wrapped with with code and remove them from the first list. Something like this:

Code: Select all

<?php

$test = 'THE DATA YOU ARE LOOKING THOUGH ';

$aryMatches = array();
if (preg_match_all('%\[posts=(\'|")?(.*?)\1?\](.*?)\[/posts\]%s', $test, $regs, PREG_SET_ORDER)) {
	$aryAll = array();
	foreach($regs as $data) {
		$data[2] = trim($data[2]);
		$data[3] = trim($data[3]);
		$aryAll[$data[2].'~'.$data[3]] = array('ID'=>$data[2],'Text'=>$data[3]);
	}

	if (preg_match_all('%\[code.*?\[posts=(\'|")?(.*?)\1?\](.*?)\[/posts\].*?\[/code\]%s', $test, $regs, PREG_SET_ORDER)) {
		foreach($regs as $data) {
			$data[2] = trim($data[2]);
			$data[3] = trim($data[3]);
			if (array_key_exists($data[2].'~'.$data[3],$aryAll)) {
				unset($aryAll[$data[2].'~'.$data[3]]);
			}
		}
	}

	foreach($aryAll as $data) { $aryMatches[] = $data; }
	unset($aryAll,$regs,$data);
}

var_dump($aryMatches);

?>

Re: [Help] Match if not between [code] [/code]

Posted: Sat Sep 17, 2011 9:57 am
by KoBE
Thanks for the reply. Using what you said I am currently using this code:

Code: Select all

function TLFcontentRestrict_newreply()
{
	global $message,$mybb;
	//$pattern = "#\[posts=(?:\"|')?(.*?)[\"']?(?:\"|')?\](.*?)\[\/posts\](\r\n?|\n?)#si";
	$pattern = "#(?:\[code\](?:.*?)\[/code\])|\[posts=(?:\"|')?(.*?)[\"']?(?:\"|')?\](.*?)\[\/posts\](\r\n?|\n?)#si";
	while(preg_match_all($pattern, $message, $matches))
	{
		$message = preg_replace_callback($pattern, "TLFnewreply", $message);
	}
}
function TLFnewreply($match) {
	global $mybb;
	$pattern = "#\[code.*?\[posts=(\'|\")?(.*?)\1?\](.*?)\[/posts\].*?\[/code\]#si";
	if(preg_match_all($pattern, $match[0], $matches)){
	$test = "should display the original match here";
	return $test;
	}
	if($mybb->user['postnum'] < $match[1]){
	//echo "-".$match[1]."-";
	return "[content removed]&#13;";
	}else{
	return "[post=".$match[1]."]".$match[2]."[/post]&#13;";
	}
}
If you can't tell, I'm creating a plugin for MyBB. so, a few variables may seem odd. It's working fine, but when I try to return $matches[0] instead of $test, it returns 'Array' but when i use print_r($matches[0]) it will print the desired code to the page. I just can't return it as a replace pattern for some reason.