Replace all urls with minified urls within a string containing mixed content

I have string with links and iam going to extract links into an array as following

$string = "The text you want to filter goes here. http://google.com, https://www.youtube.com/watch?v=K_m7NEDMrV0,https://instagram.com/hellow/";

preg_match_all('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $string, $match);

print_r($match[0]);

results

Array ( 
[0] => http://google.com 
[1] => https://www.youtube.com/watch?v=K_m7NEDMrV0 
[2] => https://instagram.com/hellow/ 
) 

Now i will use bit.ly API function gobitly() for link shorten that ends with array like this

foreach ($match[0] as $link){
    $links[] = gobitly($link);
}

the results of $links[]

Array ( 
[0] => http://t.com/1xx
[1] => http://t.com/z112
[2] => http://t.com/3431
) 

Now I want to rebuild the string and replace links to the new one to be like this

$string = "The text you want to filter goes here. http://t.com/1xx, http://t.com/z112,http://t.com/3431";

You should be able to use preg_replace_callback() to manipulate the matches and return them at once, instead of extracting them and replacing them manually (which would require a bit more work, for no real reason that I can see?). Here's a quick example

$string = "The text you want to filter goes here. http://google.com, https://www.youtube.com/watch?v=K_m7NEDMrV0,https://instagram.com/hellow/";

$replaced = preg_replace_callback('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', function($matches){
    // This function runs on each match
    $url = $matches[0];
    
    // Do bit.ly here. This is just an example
    $url = 'url/from/bit.ly/for:'.$url;
    
    // Return the new URL (which overwrites the match)
    return $url;
}, $string );

var_dump( $replaced );

This should give you an expected output like:

string(191) "The text you want to filter goes here. url/from/bit.ly/for:http://google.com, url/from/bit.ly/for:https://www.youtube.com/watch?v=K_m7NEDMrV0,url/from/bit.ly/for:https://instagram.com/hellow/"

Of course instead of that weird concatenation I have for example purposes, you'll make a request to bit.ly or whatever API you want and use that shortened URL


Since you know the key of the url to be replaced, you can simply loop over then and use str_replace to replace each shorturl with the original;

<?php

$string = "The text you want to filter goes here. http://google.com, https://www.youtube.com/watch?v=K_m7NEDMrV0,https://instagram.com/hellow/";

preg_match_all('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $string, $match);

// Shorten array
$short = [ 'http://t.com/1xx', 'http://t.com/z112', 'http://t.com/3431' ];

// For each url
foreach ($match[0] as $key => $value) {
    
    // Replace in original text
    $string = str_replace($value, $short[$key], $string);
}

echo $string;

The text you want to filter goes here. http://t.com/1xx, http://t.com/z112,http://t.com/3431

Try it online!


You need preg_replace_callback:

$newString = preg_replace_callback(
    '#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#',
    function ($match) {
        // Use for debugging purposes
        // print_r($match);

        return gobitly($match[0]);    
    },
    $string
);

Fiddle, I used md5 instead of your function.