2

I need to prepare a regular expression that can be used to remove a bbcode [QUOTE] (examples: [QUOTE=name]; [QUOTE=123;123]) tag, when it is nested within a pre-existing [QUOTE] tag.

The current regular expression I am using is from the answer here (full explanation of the regex included): Remove nested quotes

~\G(?!\A)(?>(\[quote\b[^]]*](?>[^[]+|\[(?!/?quote)|(?1))*\[/quote])|(?<!\[)(?>[^[]+|\[(?!/?quote))+\K)|\[quote\b[^]]*]\K~

However, this only removes a second or later nested [QUOTE] tag, but leaves a single nested tag, I now want to have all [QUOTE] tags removed if they are nested within an existing [QUOTE] tag.

An example of an input and how it should output from preg_replace():

//input
$string = 'Here is a quote [QUOTE=person]I am also quoting [QUOTE]this is a nested quote[/QUOTE][/QUOTE]';

//preg replace
$string = preg_replace('regular_expression', '', $string);

//output
echo $string;
// Here is a quote [QUOTE=person]I am also quoting[/QUOTE]
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
JimmyBanks
  • 4,178
  • 8
  • 45
  • 72
  • Possible duplicate of [Remove nested quotes](//stackoverflow.com/q/18754062) – mario Dec 16 '17 at 17:57
  • @mario That is the regex that I have displayed above, that I was previously using – JimmyBanks Dec 16 '17 at 18:01
  • I know. Which brings up a few questions. Why not mention so beforehand? Why pick the least readable one? And what adaptations have you tried? Right now this is just a repost without new context. So why not post a bounty on the original question simply? – mario Dec 16 '17 at 18:04
  • I've added it in now. What do you mean the least readable one? That is the only solution there that works properly. It is with new context, the solution I am looking for is not the same as the other post. – JimmyBanks Dec 16 '17 at 18:05
  • Okay my mistake, with the link to the source I don't see the benefit in me copy pasting that explanation now – JimmyBanks Dec 16 '17 at 18:12
  • 1
    Maybe `https://regex101.com/r/4vlEs4/1` will be enough? This will remove all nested QUOTEs inside an outer QUOTE. To remove all nested occurrences, you will need to replace with an empty string until no match is found. – Wiktor Stribiżew Dec 16 '17 at 19:00

1 Answers1

0

You could use a recursive approach:

(\[QUOTE[^][]*\])
(
    (?:[^][]+|(?R))+
)
\[/QUOTE\]

See a demo on regex101.com.


In PHP this would be:
$regex = '~
        (\[QUOTE[^][]*\])
        (
            (?:[^][]+|(?R))+
        )
        (\[/QUOTE\])
        ~x';

$string = 'Here is a quote [QUOTE=person]I am also quoting [QUOTE]this is a nested quote[/QUOTE][/QUOTE]';

$string = preg_replace_callback($regex, 
    function($match) {
        return $match[1] . preg_replace('~\[/?[^][]*\]~', '', $match[2]) . $match[3];
    },
    $string);

echo $string;
?>


This yields
Here is a quote [QUOTE=person]I am also quoting this is a nested quote[/QUOTE]
Jan
  • 42,290
  • 8
  • 54
  • 79