从PHP中的文本中提取URL

ahm*_*med 40 html php regex

我有这个文字:

$string = "this is my friend's website http://example.com I think it is coll";
Run Code Online (Sandbox Code Playgroud)

如何将链接提取到另一个变量?

我知道它应该是通过使用正则表达式,preg_match()但我不知道如何?

Nob*_*obu 45

可能最安全的方法是使用WordPress的代码片段.下载最新版本(目前为3.1.1)并查看wp-includes/formatting.php.有一个名为make_clickable的函数,它有param的纯文本并返回格式化的字符串.您可以获取用于提取URL的代码.虽然这很复杂.

这一行正则表达式可能会有所帮助.

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

但是这个正则表达式仍然无法删除一些格式错误的URL(例如http://google:ha.ckers.org).

另请参见: 如何模拟StackOverflow自动链接行为

  • 我玩过Wordpress formatting.php,使用make_clickable是一个不错的主意,但它最终吸收了一半依赖的wordpress. (4认同)

Mik*_*oos 15

我尝试按照Nobu的说法,使用Wordpress,但是为了与其他WordPress函数有很多依赖关系,我选择使用Nobu的正则表达式preg_match_all()并将其转换为函数,使用preg_replace_callback(); 一个函数,它现在用可点击的链接替换文本中的所有链接.它使用匿名函数,因此您需要PHP 5.3,或者您可以重写代码以使用普通函数.

<?php 

/**
 * Make clickable links from URLs in text.
 */

function make_clickable($text) {
    $regex = '#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#';
    return preg_replace_callback($regex, function ($matches) {
        return "<a href=\'{$matches[0]}\'>{$matches[0]}</a>";
    }, $text);
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意:我已经更新了您的答案,以使用匿名函数作为回调,而不是使用 `create_function()`。 (2认同)

sou*_*rge 12

URL的定义非常复杂 - 您必须先确定要捕获的内容.开始一个简单的例子捕捉任何与http://https://可能是:

preg_match_all('!https?://\S+!', $string, $matches);
$all_urls = $matches[0];
Run Code Online (Sandbox Code Playgroud)

请注意,这是非常基本的,可能会捕获无效的网址.我建议赶上POSIXPHP正则表达式来处理更复杂的事情.


Mic*_*rdt 8

如果您从中提取URL的文本是用户提交的,并且您将在任何地方将结果显示为链接,那么您必须非常非常小心地避免XSS漏洞,最突出的是"javascript:"协议URL,但也会出现格式错误网址可能会诱使你的正则表达式和/或显示浏览器进入执行它们的JavaScript网址.至少,您应该只接受以"http","https"或"ftp"开头的网址.

Jeff 还有一篇 博客文章,其中描述了提取URL的其他一些问题.


run*_*alk 5

preg_match_all('/[a-z]+:\/\/\S+/', $string, $matches);
Run Code Online (Sandbox Code Playgroud)

这是一种简单的方法,适用于很多情况,而不是所有情况。所有匹配项都放在 $matches 中。请注意,这不包括锚元素(<a href=""...)中的链接,但这也不在您的示例中。

  • @Michael:查找 javascript URL 还不是一个漏洞;使用它们没有任何检查是。有时,此类 URL 的存在和数量是有用的信息。我会选择不同的分隔符。:) (2认同)

Sha*_*ran 5

你可以这样做..

<?php
$string = "this is my friend's website http://example.com I think it is coll";
echo explode(' ',strstr($string,'http://'))[0]; //"prints" http://example.com
Run Code Online (Sandbox Code Playgroud)


Kai*_*ack 5

适合我的代码(特别是如果你的$ string中有几个链接)是:

$string = "this is my friend's website http://example.com I think it is cool, but this is cooler http://www.memelpower.com :)";
$regex = '/\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i';
preg_match_all($regex, $string, $matches);
$urls = $matches[0];
// go over all links
foreach($urls as $url) 
{
    echo $url.'<br />';
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助他人.