Removing stray brackets from in between shortcodes

I was wondering if someone could point me in the right direction for cleaning up this code.

WordPress uses shortcodes in the form [shortcode] to add extended functionality to posts and pages.

What I am trying to do is to return a string with all of the 'stray' brackets, ones not being used by any of shortcodes, as html entities.

What I have to work with are these variables via WordPress:

• $shortcode_tags: an array of all shortcodes as strings (without brackets) • get_shortcode_regex(): combines all registered shortcode tags into a single regular expression. (I am not using this in the code below) function find_stray_brackets ($content) {
// this code repalces all occurences of every shortcode with special brackets.
// It then replaces remaining 'stray' brackets with the HTML character entitiy.

global shortcode_tags;
foreach($shortcode_tags as$k=>$item) {$pattern='/$('.k.'.*?(?=$))\]/';
$content=preg_replace($pattern,'*{*$1*}*',$content);
$pattern='/$\/('.k.'.*?(?=$))\]/';$content=preg_replace($pattern,'*{*/$1*}*',$content); }$content=str_replace('[','&#91;',$content);$content=str_replace(']','&#93;',$content);$content=str_replace('*{*','[',$content);$content=str_replace('*}*',']',$content); return($content);
}


The approach is to replace all of the brackets that surround shortcodes with special characters-> replace stray brackets with html entities -> re-insert original brackets

My end goal is to put all of the text between short codes (including before the first and after the last shortcode) into an array. I couldn't get the regex that Wordpress produces to do what I wanted, so wrote my own regex that relies on brackets - this is why I need to deal with the strays.

Here is the regex that WordPress outputs and some sample text with nested shortcodes.

• I found a solution for what I was trying to do. I ended up creating my own regex like before, however using the list of shortcodes that WordPress provides - one that would only select the shortcodes themseleves, then split everything in between the brackets into an array. This dealt with the stray brackets, and cumbersome replacement schemes. – gregpress Nov 19 '14 at 1:13

You can simplify and improve this part:

$pattern = '/$('.k.'.*?(?=$))\]/';$content = preg_replace($pattern,'*{*$1*}*',$content);$pattern = '/$\/('.k.'.*?(?=$))\]/';
$content = preg_replace($pattern,'*{*/$1*}*',$content);


Instead of using two replacements for [k] and [/k], you can add the /? inside the capture group and use a single replacement:

$pattern = '/$(\/?'.k.'.*?(?=$))\]/';$content = preg_replace($pattern,'*{*$1*}*',$content);  This regex can be still improved. Is the positive look-ahead really necessary? It seems to me that this should do the job just as well: $pattern = '/$(\/?'.k.'.*?)$/';


On the other hand, this is not very strict. For example, if you have shortcode gallery, then [galleryzzz] will also match and not be treated as "stray brackets". Maybe that's fine with you, but in any case, it's easy to prevent that by adding a zero-width word boundary check:

\$pattern = '/$(\/?'.k.'\b.*?)$/';

• Thanks! combining the regex with \/? makes a lot of sense. The positive look ahead is important because sometimes shortcodes include attributes - for example 'column' needs to catch [column width=1/2]. You are right that this is not very strict. I am not a huge fan of the replacement scheme, that is relying on a separator character - seems kludgy and as well is not strict. – gregpress Nov 16 '14 at 19:53
• I asked about the look-ahead, because it seems it should work without it, even for shortcodes that include attributes – janos Nov 16 '14 at 19:58