PHP查找文本中的所有链接

时间:2014-04-29 13:57:31

标签: php regex

我想在文本中找到所有链接:

Test text http://hello.world Test text 
http://google.com/file.jpg Test text https://hell.o.wor.ld/test?qwe=qwe Test text 
test text http://test.test/test

我知道我需要使用preg_match_all,但只有头脑中的想法:从http | https | ftp开始搜索并在文本的空格或末尾出现的结束搜索,这就是我真正需要的所有,所以所有链接都将是找到了。

任何人都可以帮助我使用php regexp模式吗?

我认为我需要在模式结束时使用断言,但现在无法理解它们的正确用法。

有什么想法吗?感谢名单!

10 个答案:

答案 0 :(得分:9)

我会选择像~[a-z]+://\S+~i

这样简单的东西
  • 以协议[a-z]+://
  • 开头
  • \S+后跟一个或多个非空格,其中\S[^ \t\r\n\f] i (PCRE_CASELESS)
  • 使用shorthand $pattern = '~[a-z]+://\S+~'; $str = 'Test text http://hello.world Test text http://google.com/file.jpg Test text https://hell.o.wor.ld/test?qwe=qwe Test text test text http://test.test/test'; if($num_found = preg_match_all($pattern, $str, $out)) { echo "FOUND ".$num_found." LINKS:\n"; print_r($out[0]); } (可能不是真正的必要)

所以看起来像这样:

FOUND 4 LINKS:
Array
(
    [0] => http://hello.world
    [1] => http://google.com/file.jpg
    [2] => https://hell.o.wor.ld/test?qwe=qwe
    [3] => http://test.test/test
)

输出

{{1}}

modifier

答案 1 :(得分:2)

<?php

// The Regular Expression filter
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";

// The Text you want to filter for urls
$text = "The text you want to filter goes here. http://google.com";

// Check if there is a url in the text
if(preg_match($reg_exUrl, $text, $url)) {

       // make the urls hyper links
       echo preg_replace($reg_exUrl, "<a href="{$url[0]}">{$url[0]}</a> ", $text);

} else {

       // if no urls in the text just return the text
       echo $text;

}
?>

参考:http://css-tricks.com/snippets/php/find-urls-in-text-make-links/

答案 2 :(得分:1)

像魅力一样工作。用这个。

$str= "Test text http://hello.world";
preg_match_all('/\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i', $str, $result, PREG_PATTERN_ORDER);
print_r($result[0]);

答案 3 :(得分:1)

建议的答案很棒,但其中一个错过www.个案,另一个http://

所以,让我们结合所有这些:

$text = Test text http://hello.world Test text 
http://google.com/file.jpg Test text https://hell.o.wor.ld/test?qwe=qwe Test text 
test text http://test.test/test

preg_match_all('/(((http|https|ftp|ftps)\:\/\/)|(www\.))[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\:[0-9]+)?(\/\S*)?/', $text, $results, PREG_PATTERN_ORDER);

print_r($results[0]);

PREG_PATTERN_ORDER的返回值将是数组数组(results),因此$results[0]是完整模式匹配的数组,$results[1]是匹配的字符串数组由第一个带括号的子模式,依此类推。

答案 4 :(得分:1)

function turnUrlIntoHyperlink($string){
    //The Regular Expression filter
    $reg_exUrl = "/(?i)\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/";

    // Check if there is a url in the text
    if(preg_match_all($reg_exUrl, $string, $url)) {

        // Loop through all matches
        foreach($url[0] as $newLinks){
            if(strstr( $newLinks, ":" ) === false){
                $link = 'http://'.$newLinks;
            }else{
                $link = $newLinks;
            }

            // Create Search and Replace strings
            $search  = $newLinks;
            $replace = '<a href="'.$link.'" title="'.$newLinks.'" target="_blank">'.$link.'</a>';
            $string = str_replace($search, $replace, $string);
        }
    }

    //Return result
    return $string;
}

答案 5 :(得分:1)

函数 turnUrlIntoHyperlink($string) { // 正则表达式过滤器 $reg_exUrl = "/(http|https|ftp|ftps)://[a-zA-Z0-9-.]+.[a-zA-Z]{2,3}(/\S*)?/ ";

// Check if there is a url in the text
if (preg_match($reg_exUrl, $string, $url)) {
    // make the urls hyper links
    echo preg_replace($reg_exUrl, "<a target='_blank' href='{$url[0]}'>{$url[0]}</a>", $string);
} else {
    // if no urls in the text just return the text
    echo $string;
}

}

答案 6 :(得分:0)

替代正则表达式使用此library

效果非常好,但不适用于非常复杂的代码。

foreach($html->find('a') as $element) 
       echo $element->href . '<br>';

易于使用。不需要正则表达技能: - )

答案 7 :(得分:0)

不是regexp,但是可以找到所有内容并确保它们尚未包含在标记中。它还会检查以确保链接未封装在(),[],“”或任何其他带有打开和关闭状态的链接中。

$txt = "Test text http://hello.world Test text 
http://google.com/file.jpg Test text https://hell.o.wor.ld/test?qwe=qwe Test text 
test text http://test.test/test <a href=\"http://example.com\">I am already linked up</a>
It was also done in 1927 (http://test.com/reference) Also check this out:http://test/index&t=27";
$holder = explode("http",$txt);
for($i = 1; $i < (count($holder));$i++) {
    if (substr($holder[$i-1],-6) != 'href="') { // this means that the link is not alread in an a tag.
        if (strpos($holder[$i]," ")!==false) //if the link is not the last item in the text block, stop at the first space
            $href = substr($holder[$i],0,strpos($holder[$i]," "));
        else                                //else it is the last item, take it
            $href = $holder[$i];
        if (ctype_punct(substr($holder[$i-1],strlen($holder[$i-1])-1)) && ctype_punct(substr($holder[$i],strlen($holder[$i])-1)))
            $href = substr($href,0,-1);     //if both the fron and back of the link are encapsulated in punctuation, truncate the link by one
        $holder[$i] = implode("$href\" target=\"_blank\" class=\"link\">http$href</a>",explode($href,$holder[$i]));
        $holder[$i-1] .= "<a href=\"";
    }
}
$txt = implode("http",$holder);

echo $txt;

输出:

Test text <a href="http://hello.world" target="_blank" class="link">http://hello.world</a> Test text 
<a href="http://google.com/file.jpg" target="_blank" class="link">http://google.com/file.jpg</a> Test text <a href="https://hell.o.wor.ld/test?qwe=qwe" target="_blank" class="link">https://hell.o.wor.ld/test?qwe=qwe</a> Test text 
test text <a href="http://test.test/test" target="_blank" class="link">http://test.test/test</a> <a href="http://example.com">I am already linked up</a>
It was also done in 1927 (<a href="http://test.com/reference" target="_blank" class="link">http://test.com/reference</a>) Also check this out:<a href="http://test/index&amp;t=27" target="_blank" class="link">http://test/index&amp;t=27</a>

答案 8 :(得分:0)

要将 URL 转换为标签,以及识别没有 http/https 的 URL,请尝试以下操作。它使用 preg_replace_callback 来避免多次出现相同 URL 的其他答案之一中的问题:

  private function convertUrls($string) {
    $url_pattern = '/(((http|https)\:\/\/)|(www\.))[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(\:[0-9]+)?(\/\S*)?/';
    return preg_replace_callback($url_pattern,
      function($matches) {
        $match = $matches[0];
        if (strstr($match, ":") === false) {
          $url = "https://$match";
        } else {
          $url = $match;
        }
        return '<a href="' . $url .'" target="_blank">' . $url . '</a>';
      },
      $string);
  }

答案 9 :(得分:-1)

  

我使用此功能

  <?php
    function deteli($string){
        $pos  = strpos($string, 'http');
        $spos = strpos($string, ' ', $pos);
        $lst  = $spos - $pos;
        $bef  = substr($string, 0, $pos);
        $aft  = substr($string, $spos);
        if ($pos == true || $pos == 0) {
            $link = substr($string, $pos, $lst);
            $res  =  $bef . "<a href='" . $link . "' class='link' target='_blank'>link</a>" . $aft . ""; 
            return  $res;
        }
        else{
            return $string;
        }
    }?>