SitePoint Sponsor

User Tag List

Results 1 to 15 of 15
  1. #1
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,816
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)

    substring regex...

    Is there a way , within ONE PHP regex statement , to evaluate only part of a regex selected string? Hmm.. that doesnt seem to explain what I mean very well. Lets, for example, say you had a string of text, SOME of it contained something SIMILAR to HTML tags.. "\n<ol>\n" and "\n</ol>\n", so you wanted to preg_replace for "\n\*" BUT only in the text contained between ANY occurrence of "\n<ol>\n" and "\n</ol>\n".

    So far the only way I see of accomplishing this to use preg_match, a remembering array, run the sub-regex on the captured result from the preg_match, then another loop str_replacing items in the remembering array with the regexed captured result from the preg_match. Which is rather convoluted, even just to describe.

    Any suggestions would be greatly appreciated.

  2. #2
    Foozle Reducer ServerStorm's Avatar
    Join Date
    Feb 2005
    Location
    Burlington, Canada
    Posts
    2,699
    Mentioned
    89 Post(s)
    Tagged
    6 Thread(s)
    Hi dresden_phoenix

    Is this what your looking for:
    PHP Code:
    $text "\n<ol>\n <li>This is the text between the ol. </li> \n</ol>\n";

    /*
    * Regex searches on the new lines and the ols, 
    * then it uses a group match to get the text inbetween.
    */
    $match preg_match("/\\n<ol>\\n(.*)\\n<\/ol>\\n/"$text $matches);
    print_r($matches);

    /* Outputs */
    Array ( 
    [
    0] => This is the text between the ol.  
    [
    1] => <li>This is the text between the ol.</li
    Regards,
    Steve
    ictus==""

  3. #3
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    73 Post(s)
    Tagged
    0 Thread(s)
    I think the simple answer is 'no, it will require 2 statements.'
    Never grow up. The instant you do, you lose all ability to imagine great things, for fear of reality crashing in.

  4. #4
    Foozle Reducer ServerStorm's Avatar
    Join Date
    Feb 2005
    Location
    Burlington, Canada
    Posts
    2,699
    Mentioned
    89 Post(s)
    Tagged
    6 Thread(s)
    Wow, I have to stop answering Dresden's posts, no fault of his own but I seem to misinterpret his needs way too often. I re-read what you asked have been trying a number of things but @StarLion ; has seemed to tell you correctly.

    I promise I will steer clear of your questions in the future and sorry for the wasted post.

    Regards,
    Steve
    ictus==""

  5. #5
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,816
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)
    That suck, as normally you actually end up answering my Q's correctly, Storm.

    @ star...

    Does that mean looping statements? I mean if the original string contained multiple OLs

  6. #6
    Foozle Reducer ServerStorm's Avatar
    Join Date
    Feb 2005
    Location
    Burlington, Canada
    Posts
    2,699
    Mentioned
    89 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by dresden_phoenix View Post
    That suck, as normally you actually end up answering my Q's correctly, Storm.
    Thanks... I guess I'll keep trying and glad that I have not put you off

    Could you give a full example in an code block an specific example, is it:
    • '\n<ol>\n <li>some text \n and more text</li>\n</ol>\n' : so you would want \n<ol>\n <li>some text</li>\n</ol>\n or
    • '\n<ol>\n \n<li>some text</li>\n</ol>\n' : so it would become \n<ol>\n \n</ol>\n or
    • something else?

    I have been fiddling and found something that can give you \n<ol>\n <li></li>\n</ol>\n but I am not sure if this is helpful because if you are trying to preserve some text inside the <ol> and/or the <li> then I wanted to try something else.

    Regards,
    Steve
    ictus==""

  7. #7
    SitePoint Wizard wonshikee's Avatar
    Join Date
    Jan 2007
    Posts
    1,223
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    If I understand your question right, you have to use lookahead and lookbehind.

  8. #8
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,816
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)
    OK.. so lets say you have a block of text, you want to change any AND ALL \n* that happens to be within <OL>/</OL> to <LI> ( just to keep this task 'simple') But what you dont whant to change is any \n* that are OUTSIDE the <OL>/</OL>:

    "
    <ol>
    *Change us!
    *list item
    *list item
    </ol>
    lorem ipsum .. blah bla blah

    *dont change me
    *dont change me

    more lorem ipsum

    <ol>
    *Change us also !
    *list item
    </ol>
    lorem ipsu"


    I am probably not doing this right, but the problem with look ahead/behind in this case is that then it only changes ONE of the \n* between the tags not all. What am searching for is a way to change all occurrences of a pattern within ONLY WITHIN all occurrences of another pattern.

  9. #9
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    73 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    preg_match_all("<ol>.*?</ol>",$input,$blocks); //Find all OL's.
    $store $blocks//Create a duplicate for later use.
    $blocks preg_replace("\n","<li>",$blocks); //Change the blocks.
    $input preg_replace($store,$blocks,$input); //Insert the replacements 
    Note: This -will- fark up if you nest OL's.

    I want to say this would be easier with a recursive DOM parser....
    Never grow up. The instant you do, you lose all ability to imagine great things, for fear of reality crashing in.

  10. #10
    Foozle Reducer ServerStorm's Avatar
    Join Date
    Feb 2005
    Location
    Burlington, Canada
    Posts
    2,699
    Mentioned
    89 Post(s)
    Tagged
    6 Thread(s)
    Darn you @StarLion ; ! I have been trying to figure out the best way to do this and your solution is quite eligante!

    Thanks,
    Steve
    ictus==""

  11. #11
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,816
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)
    Sorry guys I had to put this on hold for while,

    Star
    I tired your suggestion, but i got the following sintax error

    Warning: preg_replace(): Delimiter must not be alphanumeric or backslash in - on line 41 ( the last line of your code), I also had to add delimiters to the other preg_match and first preg_replace but i figured you left that for me to do. It appears the problem arises because the regex pattern stored in the array doesnt have a delimiter?

    I tried the following alteration:
    Code:
    preg_match_all("#<ol>.*?</ol>#",$input,$blocks); //Find all OL's.
    $store = $blocks; //Create a duplicate for later use.
    foreach ($store as $k=>$v){$store[$k]="#$v#";}
    $blocks = preg_replace("#\n#","<li>",$blocks); //Change the blocks.
    $input = preg_replace(  $store ,$blocks,$input); //Insert the replacements  echo $input;
    echo $input;
    but it only changed the first \n*...:/


    any suggestions. Either way thanks for your input on this.

  12. #12
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    73 Post(s)
    Tagged
    0 Thread(s)
    foreach ($store as $k=>$v){$store[$k]="#$v#";}

    Why is that there?

    EDIT: NM, silly me. need pattern delimiters.
    Never grow up. The instant you do, you lose all ability to imagine great things, for fear of reality crashing in.

  13. #13
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    73 Post(s)
    Tagged
    0 Thread(s)
    So i got a bit more refined. Go me.

    PHP Code:
    echo preg_replace_callback("%<ol>.*?</ol>%s",create_function('$matches','return preg_replace("%\n%s","<li>",str_replace("\n</ol>","</ol>",$matches[0]));'),$input); 
    Never grow up. The instant you do, you lose all ability to imagine great things, for fear of reality crashing in.

  14. #14
    Foozle Reducer ServerStorm's Avatar
    Join Date
    Feb 2005
    Location
    Burlington, Canada
    Posts
    2,699
    Mentioned
    89 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by StarLion View Post
    So i got a bit more refined. Go me.

    PHP Code:
    echo preg_replace_callback("%<ol>.*?</ol>%s",create_function('$matches','return preg_replace("%\n%s","<li>",str_replace("\n</ol>","</ol>",$matches[0]));'),$input); 
    Yes "Go you! @StarLion ;"! Nice work using the callback and nice example of use in this context!
    ictus==""

  15. #15
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,816
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)
    BRILLIANT, STAR!!!
    Nice work using the callback and nice example of use in this context!
    ditto and thanks so much


Bookmarks

Posting Permissions

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