SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Member
    Join Date
    Aug 2009
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    preg_replace problem :(

    Hey guys,

    Really need some help with preg_replace that is driving me insane.

    I have a foreach loop such as this

    Code:
    <?php
    foreach ($example as $row){
    
    $id=$row['id'];
    $string=$row['string'];
    }
    I would like to do the following in each loop
    Code:
    <?php
    foreach ($example as $row){
    
    $id=$row['id'];
    $string=$row['string'];
    
    
    //$bad_words=array('bad','rotten');
    
    //REPLACE EACH WORD apart from "bad words" INSIDE THE STRING WITH 
    <a href="$row['id']">WORD FROM THE STRING</a>
    
    }
    Help really appreciated

    Cheers,

    Stuart

  2. #2
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Do you mean you want each word to be a link other than the bad words? Strange request but if that's what you want, here's an experimental idea:
    PHP Code:
    <?php
    $badWords 
    = array('bad''rotten');
    foreach(
    $example as $row){
        
    $id $row['id'];
        
    $string $row['string'];

        
    $LinkOpen '<a href="?id=' $id '">';
        
    $LinkClose '</a>';

        
    $stringReplaced trim(preg_replace('~([\.\,\n\s])(' implode('|'$badWords) . ')([\.\,\n\s])~'$LinkClose '$1$2$3' $LinkOpen$string));

        echo 
    $LinkOpen$stringReplaced$LinkClose;
    }
    That basically closes the link before any bad word, and opens it up again afterwards.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  3. #3
    SitePoint Member
    Join Date
    Aug 2009
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Jake that code is brilliant, thanks for helping me out, really appreciate it.

    Wondering if you know how I can actually seperate each word as a link?

    Also I made a mistake it should have been

    Code:
    $LinkOpen = '<a href="?id=' . WORD FROM THE STRING . '">';
        $LinkClose = '</a>';
    Sorry man, i suck at regex and this is killing me!

    Cheers,

    Stu

  4. #4
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Ok. So preg_match_all would be a better idea here, to separate each word. Then check the word against the list, and output.

    Its a little more intricate than that, because you need to take punctuation etc into account. Here goes!
    PHP Code:
    $badWords = array('bad''rotten');
    foreach(
    $example as $row){
        
    $id $row['id'];
        
    $string $row['string'];
        
    preg_match_all('/([A-Za-z]+)([\,\.\s\?]*)/'$String$Matches);
        foreach(
    $Matches[1] as $Match => $Word){
            if(!
    in_array($Word$badWords)){
                
    printf('<a href="%1$s">%1$s</a>'$Word);
            }else{
                echo 
    $Word;
            }
            echo 
    $Matches[2][$Match];
        }

    This would be quite the task if the text is large, so I would recommend it only for short strings.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  5. #5
    SitePoint Member
    Join Date
    Aug 2009
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    your a legend, cheers jake. great stuff

  6. #6
    SitePoint Enthusiast dyer85's Avatar
    Join Date
    Nov 2004
    Location
    L2 cache.
    Posts
    46
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jake Arkinstall View Post
    Ok. So preg_match_all would be a better idea here, to separate each word. Then check the word against the list, and output.

    Its a little more intricate than that, because you need to take punctuation etc into account. Here goes!
    That's just it, the OP's definition of a word might well be different.

    PHP Code:
    $badWords = array('bad''rotten');
    foreach(
    $example as $row){
        
    $id $row['id'];
        
    $string $row['string'];
        
    preg_match_all('/([A-Za-z]+)([\,\.\s\?]*)/'$String$Matches); 
    I assume "$string" should be "$String" in your example here. Typo?

    IMO, I think it would still be easier to use the preg_replace() approach. Also, for matching word characters, it's generally best to use the predefined \w character class, as it is locale-sensitive, so may include other characters like &#246;, &#228;, &#223;, &#226;, &#233;, &#201;, &#231;, &#199;, etc. Also, commas, dots, and question marks, in character classes, should not be escaped.

    PHP Code:
        foreach($Matches[1] as $Match => $Word){
            if(!
    in_array($Word$badWords)){
                
    printf('<a href="%1$s">%1$s</a>'$Word);
            }else{
                echo 
    $Word;
            }
            echo 
    $Matches[2][$Match];
        }

    This code fails to output anything for what you don't consider words.

    @StuartC: Perhaps this is desired behavior?

    This approach will leave "bad" words in the string, but unlinked (the original post seems to indicate that this is desired behavior).
    Code PHP:
    <?php
     
    $bad = array('bad', 'rotten');
    $data = 'Superbad, at the time of writing, has 87% on '
    	. 'Rotten Tomatoes. Not bad at all.';
     
    $re = '~
    	# Assert word boundaries
    	# This word contains letters, numbers,
    	# and dashes.
    	\b [\w-]+ \b
    ~ex';
    $link = '<a href="?id=%s">%s</a>';
    echo preg_replace(
    	$re,
     
    	// This version ignores case.
    	// Also, we ensure data is escaped.
    	'in_array(strtolower("$0"), $bad)
    		? htmlspecialchars("$0")
    		: sprintf($link, urlencode("$0"), htmlspecialchars("$0"));',
     
    	$data
    );
    "Structure padding is the use of extraneous materials to
    enhance the shape of a struct and make it more attractive
    to members of the opposite struct. (see also 'struct
    silicone.')" -- Eric Sosman

  7. #7
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)


    I wasn't aware of the \w class, good to know!

    Though whether or not the OP wants to include numbers or dashes is their choice. I also don't see the need for htmlspecialchars and urlencode though - they have no effect on numbers, letters or dashes.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  8. #8
    SitePoint Member
    Join Date
    Aug 2009
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks dyer85, really good stuff aswell. Thanks to the both of you guys for helping me out. Was really in a rut with this.Cheers

  9. #9
    SitePoint Enthusiast dyer85's Avatar
    Join Date
    Nov 2004
    Location
    L2 cache.
    Posts
    46
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jake Arkinstall View Post


    I wasn't aware of the \w class, good to know!

    Though whether or not the OP wants to include numbers or dashes is their choice. I also don't see the need for htmlspecialchars and urlencode though - they have no effect on numbers, letters or dashes.
    Indeed, what we consider a word will sometimes vary. You're right about the escape functions not being necessary here, but the issue might come up with regex changes. Also, I just realized escaping the markup would probably be best done when outputting the string as a whole.

    StuartC: good luck, and happy coding.
    "Structure padding is the use of extraneous materials to
    enhance the shape of a struct and make it more attractive
    to members of the opposite struct. (see also 'struct
    silicone.')" -- Eric Sosman


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
  •