3

I have a string that looks like this:

Bla bla %yada yada% bla bla %yada yada%

Is there a way to replace only the first two "%" (or the last two) so I can get the next output:

Bla bla <a href='link1'>yada yada</a> bla bla %yada yada%

and also, if necessary, the last two "%" so it outputs:

Bla bla <a href='link1'>yada yada</a> bla bla <a href='link2'>yada yada</a>

I can't figure out how to make the distinction between the first two and the last two so, if I want, I can be able to replace either the first or the last two marks "%" with a link. I'm using php. Thanks in advance

Regards

9
  • With your link identifier being %, it can cause a lot of errors a lot of different ways. You can get creative with the strpos function for it though. Commented Apr 24, 2013 at 8:04
  • Match with this regex: /(%[^%]+%)/g Commented Apr 24, 2013 at 8:04
  • u have to find first occurence then replace this and then find second occurnce then replace this Commented Apr 24, 2013 at 8:04
  • @Jon I don't necessarily have to use "%". I can mark it any way I want. Commented Apr 24, 2013 at 8:06
  • Then you should come up with something that you are going to stick to that is more unique and you can create a good regular expression from. BB Code was a good example of how to format something in that fashion and allow for expression replacement. ^^ Commented Apr 24, 2013 at 8:08

2 Answers 2

3

Using regex (PHP 5.3+ required) :

$string = 'Bla bla %yada yada% bla bla %yada yada%';
echo preg_replace('/%([^%]*)%/', '<a href="http://example.com">$1</a>', $string, 1) . '<br>'; // to replace the first instance.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
$links = array('http://example.com', 'http://stackoverflow.com', 'http://google.com');
$index = 0;
echo preg_replace_callback('/%([^%]*)%/', function($m) use($links, &$index){
    $m[1] = '<a href="'.$links[$index].'">'.$m[1].'</a>';
    $index++;
    // reset the index if it exceeds (N links - 1)
    if($index >= count($links)){
        $index = 0;
    }
    return $m[1];
}, $string).'<br>'; // to replace according to your array
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// To test with a string that contains more %% than the links
$string2 = 'Bla bla %yada yada% bla bla %yada yada% wuuut dsfsf %yada yada% sjnfsf %yada yada% jnsfds';
$links = array('http://example.com', 'http://stackoverflow.com', 'http://google.com');
$index = 0;
echo preg_replace_callback('/%([^%]*)%/', function($m) use($links, &$index){
    $m[1] = '<a href="'.$links[$index].'">'.$m[1].'</a>';
    $index++;
    // reset the index if it exceeds (N links - 1)
    if($index >= count($links)){
        $index = 0;
    }
    return $m[1];
}, $string2).'<br>'; // to replace according to your array

Online demo.

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

5 Comments

Works, but on some (older) servers you will get the T_FUNCTION error. To fix this you will need to name your function an then call it like this: preg_replace_callback('/%([^%]*)%/','my_function',$string). Example: codepad.org/zUMXvbEN
@Jules I know, this is assuming you're using PHP 5.3+
In this manner wouldn't I have to know the text between the %% ? Because that is my problem... I can't mess with the actual text since there are many strings in many different languages. All I have to do is make it linkable.
@Kapn0batai You wouldn't have to know what's between the %% but you will have unwanted results if it contains a % !
@Kapn0batai If you're not sure whether there is a % between %%, then you maybe should take the BB code approach like Jon said. With that said, I have a little (close) example here
0

Try this
Support for PHP 4 and PHP 5


Solution:

$string ='Bla bla %yada yada% bla bla %yada yada%';

// Count no of %
$count = substr_count($string,'%');

// Valid string pattern
if ( 0 == ($count % 2) ) {

    $urlString = $string;
    
    // Iterate for each pair of % to make it link
    for ( $i=1; $i <= $count/2 ; $i++  ) {
    
        $urlString = preg_replace('/%/', "<a href='link$i'>", $urlString, 1);
        $urlString = preg_replace('/%/', "</a>", $urlString, 1);
    }
}
// Invalid string pattern
else {
    echo "Invalid string pattern";
}

// Display generated link 
echo $urlString;

Working of preg_replace function

  • Remove first two %
    $str ='Bla bla %yada yada% bla bla %yada yada%';
    $newStr = preg_replace('/%/', '', $str, 2);
    
    echo $newStr;
    
    // Output => Bla bla yada yada bla bla %yada yada%

  • Remove last two %
    $str ='Bla bla %yada yada% bla bla %yada yada%';
    $newStr = preg_replace('/%/', '', strrev($str), 2);
    $newStr =  strrev($newStr);
    
    echo $newStr;
    
    // Output => Bla bla %yada yada% bla bla yada yada

  • Remove all %
    $str ='Bla bla %yada yada% bla bla %yada yada%';
    $newStr = preg_replace('/%/', '', $str);
    
    echo $newStr;
    
    // Output => Bla bla yada yada bla bla yada yada

Reference
https://www.php.net/preg%5Freplace

2 Comments

There's no pattern, and it doesn't allow for the opening or closing of the a tag.
If only a link, should be a comment.

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.