preg_replace_callback HELP

Discussion in 'PHP' started by Lucky Bastard, Jul 15, 2010.

  1. #1
    I've got the following preg_replace_callback:
    return preg_replace_callback('|<span class="glossary">(.*)</span>|', 'parse_content_array', $content);
    PHP:
    Which matches in $content the above span.
    I want to change this regex make it more flexible, so that it will also match the following scenarios:
    <div class="glossary">...</div>
    <ul class="glossary">...</ul>
    .....
    <anything class="glossary">...</anything>

    Also allowing the class definition to be anywhere within the tag.
    eg: <anything id="something" class="glossary"> ... </anything>
    etc

    I think, also being able to match such a case:
    eg: <anything style="something" class="firstclass glossary thirdclass"> .... </anything> (where this is more than 1 class defines)

    Many thanks
     
    Lucky Bastard, Jul 15, 2010 IP
  2. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #2
    $tags_array = array('span', 'div', 'ul', 'anything');
    $tags = implode("|", $tags_array);
    $content = preg_replace_callback('~<('.$tags.').+?class\s*=\s*"glossary">(.+?)</('.$tags.')>~i', 'parse_content_array', $content);
    PHP:
     
    danx10, Jul 15, 2010 IP
  3. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Thanks for that, it doesn't seem to work with the ul tags though. Strange.
    Eg:
    <ul class="glossary"><li>yada yada yada yada</li></ul>
     
    Lucky Bastard, Jul 15, 2010 IP
  4. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #4
    Hmm...I don't have anywhere to test the code atm, but you should get the following:

    <li>yada yada yada yada</li>

    as $input[2] within the parse_content_array() function??
     
    Last edited: Jul 15, 2010
    danx10, Jul 15, 2010 IP
  5. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Thanks you've been great help.

    From my debugging with the ul it doesn't even get into parse_content_array function.

    Also, on another note, I have been using $content[0] not $content[1] within the function parse_content_array($content), when I used 1 it returned weird results with the div/p instances.
     
    Lucky Bastard, Jul 15, 2010 IP
  6. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #6
    Hmm it works, use $input[2]...

    Example code (this will output contents of $input[2]):

    <?php
    
    function parse_content_array($input) {
    die($input[2]);
    }
    
    $content = '<ul class="glossary"><li>yada yada yada yada</li></ul>';
    $tags_array = array('span', 'div', 'ul', 'anything');
    $tags = implode("|", $tags_array);
    $content = preg_replace_callback('~<('.$tags.').+?class\s*=\s*"glossary">(.+?)</('.$tags.')>~i', 'parse_content_array', $content);
    
    ?>
    PHP:
    Whereas $input[0] would return the whole lot.
     
    danx10, Jul 15, 2010 IP
  7. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #7
    Hmmm fascinating. Can't get it to work in my wordpress php code. But as a standalone test file the above works. :s
     
    Lucky Bastard, Jul 15, 2010 IP
  8. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #8
    Must be the rest of your code then as my code works...in your case you'd be using $content[2]? can you post the parse_content_array function your using along with any supporting code (such as the usage code).
     
    danx10, Jul 15, 2010 IP
  9. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #9
    I'm actually using $content[0] as I want the div/p/ul or whatever tags to be returned with it. But I tried 2, and same problem.


    currently my function just echos the $content[0] which is why I know for the ul tag it isn't even getting into it like echo "[".$content[0]."]";
     
    Lucky Bastard, Jul 15, 2010 IP
  10. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #10
    function red_glossary_parse_content_array($content)
    {	
       echo "[".$content[0]."]";
       return $content[0];
    }
    function red_glossary_parse($content){	
    
    $tags_array = array('span', 'div', 'ul', 'li', 'p');
    $tags = implode("|", $tags_array);
    return preg_replace_callback('~<('.$tags.').+?class\s*=\s*"glossary">(.+?)</('.$tags.')>~i', 'red_glossary_parse_content_array', $content);
    
    
    }
    PHP:
     
    Lucky Bastard, Jul 15, 2010 IP
  11. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #11
    Hmm, heres a test for you, which worked for me:

    The code:

    <?php
    function parse_content_array($content) {
    echo "[".$content[0]."]";
    }
    
    $content = '<ul class="glossary"><li>yada yada yada yada</li></ul>';
    $tags_array = array('span', 'div', 'ul', 'anything');
    $tags = implode("|", $tags_array);
    $content = preg_replace_callback('~<('.$tags.').+?class\s*=\s*"glossary">(.+?)</('.$tags.')>~i', 'parse_content_array', $content);
    
    ?>
    PHP:
    It returned:

    [<ul class="glossary"><li>yada yada yada yada</li></ul>]
    Code (markup):
    Theirfore I don't see why it would'nt return that for you?
     
    danx10, Jul 15, 2010 IP
  12. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #12
    The content in theory is a large page of text, not just a single line like <ul class="glossary"><li>yada yada yada yada</li></ul>, could that be a problem, new lines etc.? though I don't see why, seeing it works with other tags.
     
    Lucky Bastard, Jul 15, 2010 IP
  13. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #13
    ps. I'm uploading it to my server, and will PM you a link to the page in question. If that is ok.
    p.p.s. Thanks so much for your efforts!!
     
    Lucky Bastard, Jul 15, 2010 IP
  14. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #14
    If new lines is the case, you could add the 's' modifier to the end of the regular expression to see if that helps;

    replace:

    $content = preg_replace_callback('~<('.$tags.').+?class\s*=\s*"glossary">(.+?)</('.$tags.')>~i', 'parse_content_array', $content);
    PHP:
    with:

    $content = preg_replace_callback('~<('.$tags.').+?class\s*=\s*"glossary">(.+?)</('.$tags.')>~is', 'parse_content_array', $content);
    PHP:
    and follow the instructions posted @ post #11 (my previous post)
     
    danx10, Jul 15, 2010 IP
  15. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #15
    Or could it be to do with the<ul> having <li> tags within it, and li being listed in the $tags_array?

    When I try with your example it returns, [<ul class="glossary"><li>yada yada yada yada</li></ul>]
    But when I add, li to $tags_array such as:
    $tags_array = array('span', 'div', 'ul', 'li');
    It returns:
    [<ul class="glossary"><li>yada yada yada yada</li>] (missing </ul>)
    Even though in your scenario at least it gets into parse_content_array, mine doesn't even get that far.
     
    Lucky Bastard, Jul 15, 2010 IP
  16. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #16
    <?php
    function red_glossary_parse_content_array($content)
    {  
       echo "[".$content[0]."]";
       return $content[0];
    }
    function red_glossary_parse($content){ 
    $tags_array = array('span', 'div', 'ul', 'li', 'p');
    $tags = implode("|", $tags_array);
    return preg_replace_callback('~<('.$tags.').+?class\s*=\s*"glossary">(.+?)</('.$tags.')>~is', 'red_glossary_parse_content_array', $content);
    }
    
    //contains new line
    $str = '<ul class="glossary"><li>yada yada yada 
    yada</li></ul>';
    echo red_glossary_parse($str);
    ?>
    PHP:
    That works, adding the 's' modifier did the trick :) -> demo: http://dan.x10.bz/test.php

    Let me know how that goes.
     
    danx10, Jul 15, 2010 IP
  17. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #17
    yes, the s worked beautifully!! wooo! ur a champ.
    Now for this missing </ul> tag in $content[0] ;)

    Or is it not passed into red_glossary_parse_content_array, and as such won't be passed out?
     
    Lucky Bastard, Jul 15, 2010 IP
  18. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #18
    The src on http://dan.x10.bz/test.php returns:

    [<ul class="glossary"><li>yada yada yada
    yada</li>]<ul class="glossary"><li>yada yada yada
    
    yada</li></ul>
    Code (markup):
    When $content[0] is wrapped within [ ] it does'nt return the ending tag whereas when its not; it does (or atleast it seems that way?)..unless its because im tired as its 2.34 am :/

    I'll do some debugging/investigating and get back to you.
     
    danx10, Jul 15, 2010 IP
  19. Lucky Bastard

    Lucky Bastard Peon

    Messages:
    406
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #19
    Haha yeah I noticed it was in the second half of the view source but not the [] part.
    But thanks much, works great now. I was trying to do this at 2:30am my time last night and couldn't work it out, so well done.
     
    Lucky Bastard, Jul 15, 2010 IP
  20. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #20
    Here you go (rectified the red_glossary_parse() function):

    <?php
    function red_glossary_parse_content_array($content)
    {  
       return "[".$content[0]."]";
    }
    function red_glossary_parse($content){
    $tags_array = array('span', 'div', 'ul', 'li', 'p');
    foreach($tags_array as $tag) {
    $content = preg_replace_callback('~<'.$tag.'.+?class\s*=\s*"glossary">(.+?)</'.$tag.'>~is', 'red_glossary_parse_content_array', $content);
    }
    return $content;
    }
    
    //contains new line
    $str = '<ul class="glossary"><li>yada yada yada
    yada</li></ul>';
    echo red_glossary_parse($str);
    ?>
    PHP:
    Let me know how that goes, so I can unsubscribe from this thread.
     
    danx10, Jul 15, 2010 IP