PHP find all links in the text - php

I want to find all links in the text like this:
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
I know i need to use preg_match_all, but have only idea in the head: start search from http|https|ftp and end search where space or end of the text appears, thats all i need really, so all links wiil be found properly.
Anyone can help me with php regexp pattern?
I think i need to use assertions in the end of pattern, but can`t understand their properly usage for now.
Any ideas? Thanx!

I'd go with something simple like ~[a-z]+://\S+~i
starts with protocol [a-z]+://
\S+ followed by one or more non-whitespaces where \S is a shorthand for [^ \t\r\n\f]
used modifier i (PCRE_CASELESS) (possibly not really necessery)
So it could look like this:
$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]);
}
outputs:
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
)
Test on eval.in

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 = ''.$link.'';
$string = str_replace($search, $replace, $string);
}
}
//Return result
return $string;
}

<?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, "{$url[0]} ", $text);
} else {
// if no urls in the text just return the text
echo $text;
}
?>
Reference:http://css-tricks.com/snippets/php/find-urls-in-text-make-links/

Works like a charm. use this.
$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]);

The suggested answers are great, but one of them miss www. case, the other http://
So, let's combine all of those:
$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]);
The return value for PREG_PATTERN_ORDER will be Array of Arrays (results) so that $results[0] is an array of full pattern matches, $results[1] is an array of strings matched by the first parenthesized subpattern, and so on.

function turnUrlIntoHyperlink($string)
{
// The Regular Expression filter
$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;
}
}

For converting URLs to tags, and recognizing URLs without http/https, try the below. It uses preg_replace_callback to avoid the issue in one of the other answers with the same URL appearing multiple times:
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 '' . $url . '';
},
$string);
}

Alternative to regexp it´s use this library
Works very good, butnot for very complex codes.
foreach($html->find('a') as $element)
echo $element->href . '<br>';
And easy to use. No regular expressions skills required:-)

Not regexp, but finds it all and makes sure that they are not already encompassed in a tag already. It also checks to make sure that the link isn't encapsulated in (), [], "" or anything else with an open and close.
$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 I am already linked up
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;
Output:
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 I am already linked up
It was also done in 1927 (http://test.com/reference) Also check this out:http://test/index&t=27

i use this function
<?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;
}
}?>

Related

String to URL but detect if url is image?

i'm trying to do something in PHP
I'm trying to get the link of an image -> store it to my DB, but I'd like the user to be able to store text before it, and after it, I've gotten my hands on a similar function for links, but the image part is missing.
As you can see the turnUrlIntoHyperlink does a regex check over the entire arg passed, turning the text that contains it to the url, so users can post something like
Hey check this cool site "https://stackoverflow.com" its dope!
And the entire argument posting to my database.
However i can't seem to get the same function working for the Convert Image, as it simply won't post and removed text before/after it before when i made the attempt.
How would i do this in a correct way, and can i combine these 2 functions in to 1 function?
function convertImg($string) {
return preg_replace('/((https?):\/\/(\S*)\.(jpg|gif|png)(\?(\S*))?(?=\s|$|\pP))/i', '<img src="$1" />', $string);
}
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 = ''.$link.'';
$string = str_replace($search, $replace, $string);
}
}
//Return result
return $string;
}
more explained in detail :
When i post a link like https://google.com/ I'd like it to be a href,
But if i post an image like https://image.shutterstock.com/image-photo/duck-on-white-background-260nw-1037486431.jpg , i'd like it to be a img src,
Currently, i'm storing it in my db and echoing it to a little debug panel,
Do you mean that you want to make an <img> inside <a> element?
Your turnUrlIntoHyperlink function have captured the url successfully, so we can just use explode to get string before and after the link.
$exploded = explode($link, $string);
$string_before = $exploded[0];
$string_after = $exploded[1];
Code example:
<?php
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)) {
// add http protocol if the url does not already contain it
$newLinks = $url[0][0];
if(strstr( $newLinks, ":" ) === false){
$link = 'http://'.$newLinks;
}else{
$link = $newLinks;
}
$exploded = explode($link, $string);
$string_before = $exploded[0];
$string_after = $exploded[1];
return $string_before.'<img src="'.$link.'">'.$string_after;
}
return $string;
}
echo turnUrlIntoHyperlink('Hey check this cool site https://stackoverflow.com/img/myimage.png its dope!');
Output:
Hey check this cool site <img src="https://stackoverflow.com/img/myimage.png"> its dope!
Edit: the question has been edited
Since an image URL is just another kind of link/URL, your logic should go like this pseudocode:
if link is image and link is url
print <img src=link> tag
else if link is url and link is not image
print <a href=link> tag
else
print link
So you can just write a new function to "merge" those two function:
function convertToImgOrHyperlink($string) {
$result = convertImg($string);
if($result != $string) return $result;
$result = turnUrlIntoHyperlink($string);
if($result != $string) return $result;
return $string;
}
echo convertToImgOrHyperlink('Hey check this cool site https://stackoverflow.com/img/myimage.png its dope!');
echo "\r\n\r\n";
echo convertToImgOrHyperlink('Hey check this cool site https://stackoverflow.com/ its dope!');
echo "\r\n\r\n";
Output:
Hey check this cool site <img src="https://stackoverflow.com/img/myimage.png" /> its dope!
Hey check this cool site https://stackoverflow.com/ its dope!
The basic idea is that since image url is also a link, such check must be done first. Then if it's effective (input and return is different), then do <img> convertion. Otherwise do <a> convertion.

Detect and Shorting long url text in php

I have long Text containg som html urls inside it from database .
im fetching it like that :
echo html_entity_decode($text);
and $text is like that in database:
$text = "this is my best <a href='http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_characters_heeeeeeeeere'>http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_characters_heeeeeeeeere</a> and some text here";
it echoes this :
this is my best http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_characters_heeeeeeeeere and some text here
But i want it display shorted text of the url and the href link is same like that :
this is my best http://www.website.com/andsoooooo... and some text here
How do i detect how long is it the link text and then short it automatically when fetching from database BUT the real link stayed as it is in href tag . thanks so much
EDIT im not looking to short the $text im looking to short the link inside the $text
Use substr():
$text = "this is my best <a href='http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_characters_heeeeeeeeere'>http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_characters_heeeeeeeeere</a>";
// Gets the whole tag
// e.g., "Text"
$linkTag = getTagFromYourUglyAssString($text, "a");
// Gets the tag's text value
// e.g., "Text"
$linkTagTextOnly = getTagTextFromYourUglyAssString($text, "a");
// Replace $linkTag with $linkTagTextOnly, whichever string you prefer ot shorten
$shortenedText = substr($linkTagTextOnly,0,10).'...';
echo $shortenedText;
function getTagFromYourUglyAssString($string, $tagname) {
$pattern = "/<$tagname ?.*>.*<\/$tagname>/";
preg_match($pattern, $string, $matches);
return array_merge($matches);
}
function getTagTextFromYourUglyAssString($string, $tagname) {
$pattern = "/<$tagname ?.*>(.*)<\/$tagname>/";
preg_match($pattern, $string, $matches);
return $matches[1];
}
EDIT: Actually, I think this is what you want:
$text = "this is my best <a href='http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_characters_heeeeeeeeere'>http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_characters_heeeeeeeeere</a>";
$shortenedLink = replaceTagTextFromYourUglyAssString($text, "a");
echo $shortenedLink;
// Should give:
// <a href="$text = "this is my best <a href='http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_characters_heeeeeeeeere">
// http://www.website.com/andsoooooooooooom_biiiiiiiiiiiiiiiig_chara...
// </a>
function replaceTagTextFromYourUglyAssString($string, $tagname) {
$pattern = "/(<$tagname ?.*>)(.*)(<\/$tagname>)/";
preg_match($pattern, $string, $matches);
if (count($matches) > 0) {
return $matches[0].substr($matches[1],0,10).'...'.$matches[2];
} else {
// do something else, 'cos no match found
}
}

PHP preg_replace multiple urls to links

I using this code to change urls to links:
<?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 http://www.ynet.co.il";
// 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, ''.$url[0].'', $text);
} else {
// if no urls in the text just return the text
echo $text;
}
?>
But every link direct to the first link How can I make foreach that will solve it?
Thanks.
Haim
Try:
$reg_exUrl = "...";
$text = "...";
echo preg_replace($reg_exUrl, '$0', $text);
Much simpler ;)

PHP preg_replace multiple url replaces

Hey I am trying to do 2 preg_replace:
1.make all urls to html links
2.make all images url to html img tag
But these regexs cancel the other one
<?php
// The Regular Expression filter
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
$reg_exImg = "!http://[a-z0-9\-\.\/]+\.(?:jpe?g|png|gif)!Ui";
// The Text you want to filter for urls
$text = "The text you want to filter goes here. http://google.comhttp://www.ynet.co.il http://dogsm.files.wordpress.com/2011/12/d7a1d7a7d795d791d799-d793d795.jpg";
// Check if there is a url in the text
$text = preg_replace($reg_exImg, '<img src=$0 >', $text);
$text = preg_replace($reg_exUrl, '$0', $text);
echo $text;
?>
How can I make that the preg_replace that make url to links dont do this to the tag?
Thanks.
Haim
This might be better as a callback.
Use just the $reg_exUrl, and do this:
$text = preg_replace_callback($reg_exUrl,function($m) {
if( preg_match("/\.(?:jpe?g|png|gif)$/i",$m[0])) {
return "<img src='".$m[0]."' />";
}
else {
return "<a href='".$m[0]."' rel='nofollow'>".$m[0]."</a>";
}
},$text);

Php link active

Well this is the function which active the link if someone put a link in message box with text.
My question is it doesn't show more than 1 link if someone put many link ex: www.yahoo.com www.gmail.com www.facebook.com, Then it's show only first link www.yahoo.com
function txt2link($text){
// force http: on www.
$text = ereg_replace( "www\.", "http://www.", $text );
// eliminate duplicates after force
$text = ereg_replace( "http://http://www\.", "http://www.", $text );
$text = ereg_replace( "https://http://www\.", "https://www.", $text );
// The Regular Expression filter
$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, $text, $url)) {
// make the urls hyper links
$text = preg_replace($reg_exUrl, ''.$url[0].'', $text);
} // if no urls in the text just return the text
return ($text);
}
$url = "Alter pot waer it your pot http://css-tricks.com/snippets/php/find-urls-in-
text-make-links/ you may click the link www.yahoo.com or you may see what is the
http://www.youtube.com say, is it right?";
echo txt2link($url);
you can run this code to see the result.
Any Idea ?
This is one that someone here helped me build up a while back, I dunno where it is on stack anymore but I still use this function to date.. This handles many urls in one shot, with or without http: with or without www. in most cases, its true this could us a bit of refining, but in all does the job really nice.
//for finding URLs within body of text and converting them to a clickable link
//checks DNS to see if its valid and if the link HTML already exists ignores it.
function titleHyper($text){
$text = preg_replace( "/(www\.)/is", "http://", $text);
$text = str_replace(array("http://http://","http://https://"), "http://", $text);
$text = str_replace(array("<a href='", "<a href=\"", "</a>", "'>", "\">"), "", $text);
$reg_exUrl = "/(http|https|ftp|ftps|)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
preg_match_all($reg_exUrl, $text, $matches);
$usedPatterns = array();
$context = stream_context_create(array(
'http' => array(
'timeout' => 5
)
));
foreach($matches[0] as $pattern){
if(!array_key_exists($pattern, $usedPatterns)){
$usedPatterns[$pattern]=true;
$the_contents = #file_get_contents($pattern, 0, $context);
if(substr(trim($pattern), 0, 8) != "https://"){
$color = "#FF0000";
}
if (empty($the_contents)) {
$title = $pattern;
} else {
preg_match("/<title>(.*)<\/title>/Umis", $the_contents, $title);
$title = $title[1];
$color = "#00FF00";
//$title = htmlspecialchars($title, ENT_QUOTES); //saving data to database
}
$text = str_ireplace($pattern, "<a style='font-size: 14px; background-color: #FFFFFF; color: $color;' href='$pattern' rel='nofollow' TARGET='_blank'> $title </a>", $text);
}
}
return $text;
}
// titleHyper() in action example:
//$text = "Some sample text with WWW.AOL.com<br />http://www.youtube.com/watch?v=YaxKiZfQcX8 <br />Anyone use www.myspace.com? <br />Some people are nuts, look at this stargate link at http://www.youtube.com/watch?v=ZKoUm6z5SzU&feature=grec_index , like aliens exist or something. http://www.youtube.com/watch?v=sfN-7HczmOU&feature=grec_index and here's a secure site https://familyhistory.hhs.gov, unless you use curl or allow secure connections it will never get a title. <br /> This is a not valid site http://zzzzzzz and this is a dead site http://zwzwzwxzw.com.<br /> Lastly lets try an already made hyperlink and see what it does <a href='http://tacobell.com'>taco bell</a>";
//echo titleHyper($text);

Categories