在包含混合内容的字符串中用缩小的 url 替换所有 url

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

我有带 links 的字符串,我打算将 links 提取到数组中,如下所示

$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]);

结果

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

现在我将使用 bit.ly API 函数 gobitly() 缩短以 array 结尾的 link 像这样

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

$links[]

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

现在我想重建 string 并将 link 替换为新的

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

你需要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,我用了md5而不是你的函数。

您应该可以使用 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 );

这应该会给你一个预期的输出:

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/"

当然,您可以向 bit.ly 或任何您想要的 API 发出请求,并使用缩短的 URL

因为你知道要替换的url的key,你可以简单地循环然后使用str_replace将每个shorturl替换为原来的;

<?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!