php urlencode 重写后输出错误

php urlencode produces wrong output after rewriting

目前在 php5.6。似乎不可能对 preg_replace.

的匹配项进行 urlencode
$message = preg_replace('#(https?:\/\/www.domain.nl)(.*)#si', 'https://www.affiliatedomain.com/cread.php?id=1234&affid=12345&clickref=me&p=', $message, 1);

所以我尝试使用 preg_replace_callback。

$message = preg_replace_callback('#(https?:\/\/www.domain.nl)(.*)#Usi', function($matches) { return 'https://www.affiliatedomain.com/cread.php?id=1234&affid=12345&clickref=me&p='.urlencode('[['.$matches[0].']]'); }, $message, 1);

部分有效,也尝试了 $matches[1].$matches[2] 而不是 $matches[0]。

我假设:

$matches[0] = everything matched
$matches[1] = https://www.domain.nl
$matches[2] = /internet

当我尝试替换 https://www.domain.nl/internet 时,我希望它成为输出:

https://www.affiliatedomain.com/cread.php?id=1234&affid=12345&clickref=me&p=%5B%5Bhttps%3A%2F%2Fwww.domain.nl%2Finternet%5D%5D

但我得到的是:

https://www.affiliatedomain.com/cread.php?id=1234&affid=12345&clickref=me&p=%5B%5Bhttps%3A%2F%2Fwww.domain.nl%2F%5D%5Dinternet

无论我怎么试,我都弄不明白。在这里研究几个模拟线程,但无济于事。希望高手给个解决办法。

您可以使用

'~\shref=[\'"]\Khttps?://www\.domain\.nl(?:/[^\s"\'<>]*)?~i'

regex demo

详情

  • \s - 一个空格
  • href= - href=
  • ['"] - 一个 '"
  • \K - 匹配重置运算符丢弃目前匹配的所有文本
  • https?://www\.domain\.nl - https://www.domain.nlhttp://www.domain.nl
  • (?:/[^\s"\'<>]*)? - 可选序列:
    • / - 一个 / 字符
    • [^\s"\'<>]* - 除空格外的 0 个或更多字符,"'<>

参见 PHP demo:

$message = '<a href="https://www.domain.nl/internet" target="_blank" title="https://www.domain.nl/internet">https://www.domain.nl/internet</a>';

$message = preg_replace_callback('~\shref=[\'"]\Khttps?://www\.domain\.nl(?:/[^\s"\'<>]*)?~i', function($matches) { 
    return 'https://www.affiliatedomain.com/cread.php?id=1234&amp;affid=12345&amp;clickref=me&amp;p=' . urlencode('[[' . $matches[0] . ']]'); 
}, $message);
echo $message; // => <a href="https://www.affiliatedomain.com/cread.php?id=1234&amp;affid=12345&amp;clickref=me&amp;p=%5B%5Bhttps%3A%2F%2Fwww.domain.nl%2Finternet%5D%5D" target="_blank" title="https://www.domain.nl/internet">https://www.domain.nl/internet</a>

您可以使用 1 limit 参数指定替换第一次出现的 preg_replace_callback:

$message = preg_replace_callback('~https?://www\.domain\.nl(?:/[^\s"\'<>]*)?~i', function($matches) { 
    return 'https://www.affiliatedomain.com/cread.php?id=1234&amp;affid=12345&amp;clickref=me&amp;p=' . urlencode('[[' . $matches[0] . ']]'); 
}, $message, 1);