如何使用preg_replace替换链接和图像链接

时间:2014-07-01 17:05:23

标签: php preg-replace preg-match preg-match-all preg-replace-callback

我的文字包含图片的链接和链接,并且可以有很多链接并与其他单词混合。 下面的文字是我的示例文字。

$string = "http://www.google.com/ is best know for search engine, this is Google logo ##https://www.google.com/images/srpr/logo11w.png##. And you can visit http://www.youtube.com/ to watch videos. Here YouTube's logo ##http://s.ytimg.com/yts/img/pixel-vfl3z5WfW.gif##";

我想使用preg_replace来替换它们。

$string = '<a href="http://www.google.com/">http://www.google.com/</a> is best know for search engine, this is Google logo <img src="https://www.google.com/images/srpr/logo11w.png" />. And you can visit <a href="http://www.youtube.com/">http://www.youtube.com/</a> to watch videos. Here YouTube's logo <img src="http://s.ytimg.com/yts/img/pixel-vfl3z5WfW.gif"></img>';

这是链接的preg_replace模式。

$string = preg_replace("/([\w]+:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/i","<a target=\"_blank\" href=\"$1\">$1</a>",$string);

图片为preg_replace

$string = preg_replace("/\#\#([\w]+:\/\/[\w-?&;#~=\.\/\@]+[\w\/])\#\#/i","<img src=\"$1\"></img>",$string);

它们都运作良好,但它们不会在链接和图像链接之间分开。请帮助我,谢谢我一整天都在尝试。

2 个答案:

答案 0 :(得分:2)

您正在寻找的可能preg_replace_callback可以根据匹配结果更改替换字符串:

$str = preg_replace_callback('~(##)?\b((?:f|ht)tps?://\S+)(?(1)##|(?=\s|$|\pP))~',
                       function ($m) {
                           if (isset($m[1])) return '<img src="' . $m[2] . '"/>';
                           return '<a href="' . $m[2] . '">' . $m[2] . '</a>';
                       },
                       $str);

模式详细信息:

模式使用末尾(?(1)...|...)的特定功能,这是一个条件(如果捕获组1存在,那么尝试其他尝试)

\pP是包含所有pongctuation字符的字符类\p{Punct}的快捷方式。我把它放在交替处理这种字符串:blah blah (http://domain.com/file.html)

由于描述URL的模式非常基本(IMO,它试图制作更复杂的模式来描述URL,所以没有时间),为了确保URL正确,您可以检查它在回调函数中使用filter_var

答案 1 :(得分:2)

因为链接之间唯一可靠的区别是#hash标记,我认为你需要使用Positive Lookbehind在正则表达式之间添加另一层唯一性。

  1. 第一个正则表达式查找网址没有哈希标记来制作这些锚标记

    /((?<!##)https?:\/\/[\w-?#&;~=\.\/\@]+[\w\/])/i

  2. 然后,查找带有哈希标记的任何链接并制作那些img标记

    /\#\#(https?:\/\/[\w-?#&;~=\.\/\@]+[\w\/])\#\#/i

  3. 我还必须替换[\ w] +:在每个正则表达式的开头用更具体的东西,因为\ w看起来匹配#,所以我改变了[\ w] +:用https?:来匹配http:或https:

  4. 所以最终的两件式正则表达式看起来像这样

    $string = preg_replace("/((?<!##)https?:\/\/[\w-?#&;~=\.\/\@]+[\w\/])/i","<a target=\"_blank\" href=\"$1\">$1</a>",$string);
    $string = preg_replace("/\#\#(https?:\/\/[\w-?#&;~=\.\/\@]+[\w\/])\#\#/i","<img src=\"$1\"></img>",$string);
    

    我对此进行了测试,看起来对我的使用是有用的。