0
[quote=Username here]quoted text here[/quote]

Reply text here

I need a regular expression that stores the "Username here", "quoted text here" and "Reply text here" in a Array.

This expression needs to support nesting aswell. Eks:

[quote=Username2 here][quote=Username here]quoted text here[/quote]

Reply text here[/quote]

Reply text here
2
  • 2
    Regexes don't do nesting. They're not powerful enough. You should think about writing a proper stack-based parser that can do nesting arbitrarily deep. Commented Mar 4, 2010 at 14:15
  • What is the desired output from the nested example? Is there a limit on how deeply the quotes can be nested? Commented Mar 4, 2010 at 14:18

2 Answers 2

3

This regex matches nested quote block (in group 1) with an additional last reply (in group 2):

(\[quote=[^]]*](?:(?R)|.)*\[/quote])(.*)

A little demo:

$text = '[quote=Username2 here][quote=Username here]quoted text[/quote]Reply text[/quote]More text';
preg_match('#(\[quote=[^]]*](?:(?R)|.)*\[/quote])(.*)#is', $text, $match);
print_r($match);

produces:

Array
(
    [0] => [quote=Username2 here][quote=Username here]quoted text[/quote]Reply text[/quote]More text
    [1] => [quote=Username2 here][quote=Username here]quoted text[/quote]Reply text[/quote]
    [2] => More text
)

A little explanation:

(                  # open group 1
  \[quote=[^]]*]   #   match '[quote= ... ]'
  (?:(?R)|.)*      #   recursively match the entire pattern or any character and repeat it zero or more times
  \[/quote]        #   match '[/quote]'
)                  # open group 1
(                  # open group 2
  .*               #   match zero or more trailing chars after thae last '[/quote]'
)                  # close group 2

But, using these recursive regex constructs supported by PHP might make ones head spin... I'd opt for a little parser like John Kugelman suggested.

Sign up to request clarification or add additional context in comments.

Comments

0

Assuming you do not want to return the values nested in some way or with quotes matched - which are impossible in a regex - you can just split on the parts you do not need:

preg_split('/(\[quote=|\[quote]|]|\[/quote])/', $yourstring);

6 Comments

That will not match arbitrary nested quote blocks.
As I said: some things you cannot do in a regular expression. Matching with nesting is one such thing. Very unfair to subtract points when I cannot get you the mathematically impossible.
Apologies, I though you posted a preg_match(...) solution, I now see it was a preg_split(...). I will remove my down-vote.
Note that all regex implementations that support look-arounds, back references etc. cannot be considered mathematical "regular". And when an implementation does not support recursive constructs, you can still match a fixed number of nested tags by using look-aheads.
Ah well, your solution does win hands down.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.