Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Regular Coder
    Join Date
    Feb 2006
    Location
    The Netherlands
    Posts
    106
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Question {PCRE} Nested [quote]s to be replaced with <blockquote>s

    Hey, I'd like my visitors to be able to quote eachother's replies. Now, they have the [quote] tag available and it is replaced by <blockquote> by code like the following:

    PHP Code:

    $somereply 
    'Hey, I feel like [quote]quoting someone that is [quote]quoting 
    someone[/quote], cool, eh?[/quote].'
    ;

    $somereply preg_replace('[\[quote\](.*)\[/quote\]]iUs'
        
    '<blockquote>$1</blockquote>'
        
    $somereply); 
    Now, this basically works for normal quotes, however, when quotes are nested as in the above example, it is totally messed up. How can I fix this?

    Thanks in advance.
    Yeah that.

  • #2
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    afaik you can't do arbitrary level recursion purely with a regular expression, at least as it's implemented here. You'll need to loop over your already correct expression.

    PHP Code:
    $regex '/\[quote\](.*)\[\/quote\]/usi';
    for (; 
    preg_match($regex$somereply); $somereply preg_replace($regex'<blockquote>$1</blockquote>'$somereply)); 
    If you don't like the for abuse you can do the same thing with while.

  • #3
    Regular Coder trib4lmaniac's Avatar
    Join Date
    Feb 2004
    Location
    Cornwall, UK
    Posts
    535
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by ralph l mayo
    PHP Code:
    $regex '/\[quote\](.*)\[\/quote\]/usi'
    This would match:
    PHP Code:
    [quote]First quote[/quote]
    some text
    [quote]Second quote[/quote

  • #4
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    You're right, it needs a lazy quantifier.

    $regex = '/\[quote\](.*?)\[\/quote\]/usi';
    Last edited by ralph l mayo; 05-05-2006 at 04:01 PM.

  • #5
    Regular Coder
    Join Date
    Feb 2006
    Location
    The Netherlands
    Posts
    106
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by ralph l mayo
    You're right, it needs a lazy quantifier.

    $regex = '/\[quote\](.*?)\[\/quote\]/usi';
    Isn't that just the same as
    PHP Code:
    '/\[quote\](.*)\[\/quote\]/si'
    Yeah that.

  • #6
    fci
    fci is offline
    Senior Coder
    Join Date
    Aug 2004
    Location
    Twin Cities
    Posts
    1,345
    Thanks
    0
    Thanked 0 Times in 0 Posts
    vin0rz,
    By default, the quantifiers are "greedy", that is, they match as much as possible (up to the maximum number of permitted times), without causing the rest of the pattern to fail. The classic example of where this gives problems is in trying to match comments in C programs. These appear between the sequences /* and */ and within the sequence, individual * and / characters may appear. An attempt to match C comments by applying the pattern /\*.*\*/ to the string /* first comment */ not comment /* second comment */ fails, because it matches the entire string due to the greediness of the .* item.

    However, if a quantifier is followed by a question mark, then it ceases to be greedy, and instead matches the minimum number of times possible, so the pattern /\*.*?\*/ does the right thing with the C comments. The meaning of the various quantifiers is not otherwise changed, just the preferred number of matches. Do not confuse this use of question mark with its use as a quantifier in its own right. Because it has two uses, it can sometimes appear doubled, as in \d??\d which matches one digit by preference, but can match two if that is the only way the rest of the pattern matches.
    http://us2.php.net/manual/en/referen...ern.syntax.php

  • #7
    Regular Coder
    Join Date
    Feb 2006
    Location
    The Netherlands
    Posts
    106
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I know, but you're using the "U" modifier, which turns it around.

    Edit: Sorry, you don't use the capital u.
    Yeah that.

  • #8
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    I don't even know what u/U is supposed to do, I just copied it without thinking I guess. But then I changed it. Who knows. Get rid of it and use the ?, I say.

  • #9
    Regular Coder trib4lmaniac's Avatar
    Join Date
    Feb 2004
    Location
    Cornwall, UK
    Posts
    535
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by ralph l mayo
    I don't even know what u/U is supposed to do, I just copied it without thinking I guess. But then I changed it. Who knows. Get rid of it and use the ?, I say.
    Sadly, this still wouldn't work for capturing the outer quote:

    {quote}{quote}Inner quote.{/quote}Outer quote.{/quote]}

    In case you're wondering, I don't have a solution
    I once posted a similar problem on these boards (a year or two ago) for parsing nested {LIST} items. They're a little trickier than quotes, but it's the same principle.

  • #10
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    Quote Originally Posted by trib4lmaniac
    Sadly, this still wouldn't work for capturing the outer quote:

    {quote}{quote}Inner quote.{/quote}Outer quote.{/quote]}
    Sure it does, but the loop is needed.

    PHP Code:
    $somereply '[quote][quote]Inner quote.[/quote]Outer quote.[/quote]';
    $regex '/\[quote\](.*?)\[\/quote\]/i';
    for (; 
    preg_match($regex$somereply); $somereply preg_replace($regex'<blockquote>$1</blockquote>'$somereply)); 
    As I said, I don't think it's possible to do this correctly over N levels without looping the expression.
    Last edited by ralph l mayo; 05-08-2006 at 03:09 AM.

  • #11
    Senior Coder
    Join Date
    Aug 2003
    Location
    One step ahead of you.
    Posts
    2,815
    Thanks
    0
    Thanked 3 Times in 3 Posts
    It still would fail or match the open/close tags out of order. I'm pretty sure you need something more than just regex for this kind of stuff.
    I'm not sure if this was any help, but I hope it didn't make you stupider.

    Experience is something you get just after you really need it.
    PHP Installation Guide Feedback welcome.

  • #12
    Regular Coder
    Join Date
    Feb 2006
    Location
    The Netherlands
    Posts
    106
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Looping worked, I omitted the ? and replaced the u with U. Thanks a lot!
    Yeah that.

  • #13
    Regular Coder trib4lmaniac's Avatar
    Join Date
    Feb 2004
    Location
    Cornwall, UK
    Posts
    535
    Thanks
    0
    Thanked 0 Times in 0 Posts
    You have matched the tags out of order. Simple, yet effective

    Match 1: {quote}{quote}Inner quote.{/quote}Outer quote.{/quote}
    Replacement: <blockquote>{quote}Inner quote.</blockquote>Outer quote.{/quote}

    Match 2: <blockquote>{quote}Inner quote.<blockquote>Outer quote.{/quote}
    Replacement: <blockquote><blockquote>Inner quote.</blockquote>Outer quote.</blockquote>

    I wonder if there are any situations when this would fail.

  • #14
    Regular Coder
    Join Date
    Feb 2006
    Location
    The Netherlands
    Posts
    106
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by trib4lmaniac
    You have matched the tags out of order. Simple, yet effective

    Match 1: {quote}{quote}Inner quote.{/quote}Outer quote.{/quote}
    Replacement: <blockquote>{quote}Inner quote.</blockquote>Outer quote.{/quote}

    Match 2: <blockquote>{quote}Inner quote.<blockquote>Outer quote.{/quote}
    Replacement: <blockquote><blockquote>Inner quote.</blockquote>Outer quote.</blockquote>

    I wonder if there are any situations when this would fail.

    Yeah I had figured that out too, and wondered about it too. I think there might be a problem in a case like quote}Here comes the{quote}Inner quote{/quote}but I has a typo in the opening{/quote}
    But I think I couldn't care less, as typo's are a problem anyway.
    Yeah that.

  • #15
    Senior Coder
    Join Date
    Aug 2003
    Location
    One step ahead of you.
    Posts
    2,815
    Thanks
    0
    Thanked 3 Times in 3 Posts
    If there is an equal number or open/close tags it should work, but if there are missing opening/closing tags the wrong tags might be replaced.
    I'm not sure if this was any help, but I hope it didn't make you stupider.

    Experience is something you get just after you really need it.
    PHP Installation Guide Feedback welcome.


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •