In WordPress we are able to use shortcode function in the publish content by using this format:

[shortcode]data[/shortcode]

for instance:

[shortcode]Lorem ipsum[/shortcode] dolor sit amet, consectetur adipiscing elit. Praesent laoreet fermentum lacinia. Ut molestie purus interdum lacus pharetra placerat.

My real question is, what's the regular expression that we have to replace any text within the publish content Except the main one within the shortcode?

Thanks.

Question does not say what text to become changed by what. Think about this code to complete search/alternative of some pattern outdoors shortcode tag.

Objective: To italicize each occurrence of foo although not inside shortcode tag.

$str = "foo
 bar[shortcode]foo[/shortcode]foo 123
 bar [shortcode]foo[/shortcode] foo"; // post content
$query = "foo"; // search pattern

$query = preg_quote($query, '~');
$p = '~((\[shortcode\])(?(2).*?\[/shortcode\])(?:.*?))*?(' . $query . ')~smi';
$s = preg_replace($p, "$1<i>$3</i>", $str);
var_dump($s);

OUTPUT

String(100) "<i>foo</i>
 bar[shortcode]foo[/shortcode]<i>foo</i> 123
 bar [shortcode]foo[/shortcode] <i>foo</i>"

As you can tell above output encloses search text foo to italicized text ONLY outdoors the shortcode tag.

The next regex will match everything that's in-between shortcode tags, and little else:

  • (?<=\[shortcode]).*?(?=\[/shortcode])

It searches for positions immediately after [shortcode], then matches any string -- as short as you possibly can -- that finishes before [/shortcode].

If you wish to print each one of these inbetween-strings in PHP, you'll need code such as this:

preg_match_all('%(?<=\[shortcode\]).*?(?=\[/shortcode\])%s',
                               $input, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
    echo $result[0][$i];
}

If you wish to make use of the caught text outdoors the loop, then replace the echo $result[0][$i]; line with:

  • $output .= $result[0][$i];
s/.*\[shortcode]([^[]*)\[\/shortcode].*/\1/gm