Regular expressions in PHP / find "<a> </a>" - php

I want to check a textarea. If the user enter some links in the textarea, php should automatically tag the links. I'm using this code:
$message = "text with some link within";
$url = '#(?!<a[^>]*?>)(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])(?![^<]*?</a>)#';
if(preg_match($url, $message) == 1){
$message = preg_replace($url, '$0', $message);
}
The problem is, when there's already a tagged link (with an "a" tag), regex is destroying the link.
Here is an example:
first input from textarea: Hello .... test.com
changed by regex: Hello ... test.com
this is working fine, but if you update this:
Hello ... http://test.com" target="_blank" rel="nofollow" title="test.com" target="_blank" rel="nofollow" title="test.com">test.com">test.com">test.com
Thanks for your help!

I'm not familiar with PHP and maybe this is not a good pattern for url validation, but the point is if there is already an "a" tag, the text is not replaced.
<?php
$message = array(
'Hello ... test.com',
"Hello .... http://www.test.com ..."
);
$url = '#(<a[^>]*>[^<]+</a>|((https?://)?[\w\.-]+\.[a-zA-Z]{2,3}[^\s\W]*))#';
foreach ($message as $msg) {
preg_match($url, $msg, $matches);
if(preg_match($url, $msg) == 1 && count($matches) > 2) {
$msg = preg_replace($url, '$0', $msg);
}
echo $msg.PHP_EOL;
}
// Output:
// Hello ... test.com
// Hello .... http://www.test.com ...
Hope it helps.

Related

Find all hyperlinks and add another redirect link within a text

I want to find all hyperlinks in text and adding a link redirect to every link
Example text
Hello Visit our website Here
The result I want is
Hello Visit our website Here
The code I have tried
$reg_exUrl = "/<a\s[^>]*href=(\\\" ??)([^\\\" >]*?)\\1[^>]*>(.*)<\/a>/siU";
$text = 'Hello visit our website Book';
if(preg_match($reg_exUrl, $text, $url)) {
echo preg_replace($reg_exUrl, ''.$url[2].'', $text);
} else {
echo $text;
}
So the result of my code is
Hello visit our website Book">https://example.com
Which in HTML inspect is
Hello visit our website Book">https://example.com</a>
$text = preg_replace_callback('#(<a[^>]+href=")([^"]+)(")#', 'add_track_callback', $text);
function add_track_callback($matches){
$track_url_base = 'https://mywebsite.com?q=';
return $matches[1] . $track_url_base . urlencode($matches[2]) . $matches[3];
}
Change $track_url_base as you need.
When there are no other attributes:
$string = preg_replace('~<a href="[^"]+">~', '<a href="#">', $string);
Otherwise:
$string = preg_replace('~<a ([^>]*)href="[^"]+"([^>]*)>~', '<a \\1href="#"\\2>', $string);
Demo:
php > $string = 'text....<a asd="blub" href="orig-link" title="bla"> Link text </a> other text .....';
php > echo preg_replace('~<a ([^>]*)href="[^"]+"([^>]*)>~', '<a \\1href="#"\\2>', $string); text....<a asd="blub" href="#" title="bla"> Link text </a> other text

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
}
}

preg_match - what's wrong with this code?

$message contains two different Youtube videos. The code below works but the problem is that the end result produces two iframes with the same video ID (the first video). How can I solve this problem?
$message = 'This is a text with 2 Youtube videos: https://www.youtube.com/watch?v=rxwMjB-Skao csassasas http://www.youtube.com/watch?v=VWEwWECAokU Enf of text';
$reg_exUrl_youtube = "/(?:http(?:s)?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?&\"'> \r\n]+)(?![^<]*>)/";
if (preg_match($reg_exUrl_youtube, $message, $youtubeUrlData) ) {
$message = preg_replace($reg_exUrl_youtube, "<iframe title=\"{$youtubeUrlData[1]}\" class=\"youtube\" src=\"[qqqqq].youtube.com/embed/{$youtubeUrlData[1]}\" frameborder=\"0\" allowFullScreen></iframe>", $message);
}
1) The fix for your code is to use $1 instead of {$youtubeUrlData[1]} in the preg_replace() call:
$message = preg_replace($reg_exUrl_youtube, "<iframe title=\"$1\" class=\"youtube\" src=\"[qqqqq].youtube.com/embed/$1\" frameborder=\"0\" allowFullScreen></iframe>", $message);
2) Another implementation with preg_replace_callback(), which is very reliable from my experience, just as an example:
$message = 'This is a text with 2 Youtube videos: https://www.youtube.com/watch?v=rxwMjB-Skao csassasas http://www.youtube.com/watch?v=VWEwWECAokU Enf of text';
$reg_exUrl_youtube = "/(?:http(?:s)?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?&\"'> \r\n]+)(?![^<]*>)/";
$finalString = preg_replace_callback($reg_exUrl_youtube, function($matches) {
return "<iframe title=\"{$matches[1]}\" class=\"youtube\" src=\"[qqqqq].youtube.com/embed/{$matches[1]}\" frameborder=\"0\" allowFullScreen></iframe>";
}, $message);
echo htmlentities($finalString);
Why use an error prone regex?
Much simpler:
$message = 'This is a text with 2 Youtube videos: https://www.youtube.com/watch?v=rxwMjB-Skao csassasas http://www.youtube.com/watch?v=VWEwWECAokU Enf of text';
$a=explode(' ',$message);
foreach($a as $v){
if(strpos($v,'http')!==false && strpos($v,'youtube')!==false){
$res[]=$v;
}
}
echo var_dump($res);

php script to recognize text from link

I was trying to create a script in php, for displaying messages. If the messages includes a web address, then this address I wanted to be displayed as a link. This is my code that works successfuly:
<?php
if( (substr( $message, 0, 8 ) === "https://") || (substr( $message, 0, 7 ) === "http://") ){
echo "<a href='$message' target='_blank'> $message </a>";
}else{
echo " $message ";
}
?>
It is working perfect if the user inserts in message a web address only like: "http://google.com" The problem starts if the users inserts a text before or after the web address. For example if writes: "visit http://google.com site" then it is making all the phrase as a link and it does not recognises the words with the web address. Any idea how to fix this problem?
You may use filter_var with FILTER_VALIDATE_URL:
$words = explode(" ", $message);
$_words = array();
foreach($words as $word){
if(filter_var($word, FILTER_VALIDATE_URL) === false){
$_words[] = $word;
}
else{
$_words[] = "$word";
}
}
echo implode(" ", $_words);
Demo: http://phpfiddle.org/main/code/mu8-vg5
I use this within a class:
public static function CreateLinks($text) {
return preg_replace('#(https?://([-\w.]+[-\w])+(:\d+)?(/([\w-.~:/?#\[\]\#!$&\'()*+,;=%]*)?)?)#', '$1', $text);
}
To use it without a class, do this:
$message = preg_replace('#(https?://([-\w.]+[-\w])+(:\d+)?(/([\w-.~:/?#\[\]\#!$&\'()*+,;=%]*)?)?)#', '$1', $message);
So in a test case this:
$message = "Hello, take a look at http://www.google.com or wait! Maybe you where looking for http://www.bing.com";
$message = preg_replace('#(https?://([-\w.]+[-\w])+(:\d+)?(/([\w-.~:/?#\[\]\#!$&\'()*+,;=%]*)?)?)#', '$1', $message);
echo $message;
Will output:
Hello, take a look at http://www.google.com or wait! Maybe you where looking for http://www.bing.com
So, at the end your code can be replaced by just one single line! Replace this:
if( (substr( $message, 0, 8 ) === "https://") || (substr( $message, 0, 7 ) === "http://") ){
echo "<a href='$message' target='_blank'> $message </a>";
}else{
echo " $message ";
}
by this:
$message = preg_replace('#(https?://([-\w.]+[-\w])+(:\d+)?(/([\w-.~:/?#\[\]\#!$&\'()*+,;=%]*)?)?)#', '$1', $message);
Jan Goyvaerts, Regex Guru, describe pretty well in his blog
http://www.regexguru.com/2008/11/detecting-urls-in-a-block-of-text/
To find all matches in a multi-line string, use
preg_match_all('/\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&##\/%=~_|$?!:,.]*[A-Z0-9+&##\/%=~_|$]/i', $subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];
you can use preg_match function to get single match

php - find link to image in text and convert to link

I would like to implement the following feature onto my site. When a user posts something, he is also allowed to include one link, which is a link to a picture. Imagine a user posts something like this:
Hello look at this awesome picture. It is hilarious isn't it?
http://www.google.com/image.jpg
Then that text should be converted to:
Hello look at this awesome picture. It is hilarious isn't it?
<a target="_blank" href="http://www.google.com/image.jpg">
<img src="http://www.google.com/image.jpg" alt=""/>
</a>
So I need some php script that searches through the text for links and if it finds a link, checks that it links to a picture. It also needs to be able to recognize links that do not start with http, and also links that start with https.
How would you do that?
Thanks a lot :)
Dennis
how about these two links combined:
best way to determine if a URL is an image in PHP
PHP Regular Expression Text URL to HTML Link
$url="http://google.com/image.jpg";
function isImage( $url ){
$pos = strrpos( $url, ".");
if ($pos === false)
return false;
$ext = strtolower(trim(substr( $url, $pos)));
$imgExts = array(".gif", ".jpg", ".jpeg", ".png", ".tiff", ".tif"); // this is far from complete but that's always going to be the case...
if ( in_array($ext, $imgExts) )
return true;
return false;
}
$test=isImage($url);
if($test){
$pattern = '/((?:[\w\d]+\:\/\/)?(?:[\w\-\d]+\.)+[\w\-\d]+(?:\/[\w\-\d]+)*(?:\/|\.[\w\-\d]+)?(?:\?[\w\-\d]+\=[\w\-\d]+\&?)?(?:\#[\w\-\d]*)?)/';
$replace = '$1';
$msg = preg_replace( $pattern , $replace , $msg );
return stripslashes( utf8_encode( $msg ) );
}
This is the working code for this:
<?php
$sad222="somthing text bla bla bla ...... Https://cdn.fileinfo.com/img/ss/lg/jpg_44.JPG this is my picture.";
$d11="";$cs11 = array();$i=-1;
$sad111 = explode(" ",$sad222);
foreach ($sad111 as $sad)
{
if(strtolower(substr($sad,0,7))=="http://"||strtolower(substr($sad,0,7))=="ftps://"||strtolower(substr($sad,0,8))=="https://"||strtolower(substr($sad,0,6))=="ftp://"){
if(strtolower(substr($sad,strlen($sad)-4,4))==".jpg"||strtolower(substr($sad,strlen($sad)-4,4))==".jpe"||strtolower(substr($sad,strlen($sad)-4,4))==".jif"||strtolower(substr($sad,strlen($sad)-4,4))==".jfi"||strtolower(substr($sad,strlen($sad)-4,4))==".gif"||strtolower(substr($sad,strlen($sad)-4,4))==".png"||strtolower(substr($sad,strlen($sad)-4,4))==".bmp"||strtolower(substr($sad,strlen($sad)-4,4))==".dib"||strtolower(substr($sad,strlen($sad)-4,4))==".ico"||strtolower(substr($sad,strlen($sad)-5,5))==".jpeg"||strtolower(substr($sad,strlen($sad)-5,5))==".jfif"||strtolower(substr($sad,strlen($sad)-5,5))==".apng"||strtolower(substr($sad,strlen($sad)-5,5))==".tiff"||strtolower(substr($sad,strlen($sad)-4,4))==".tif"){
$d11="<img src='".$sad."' width='500' height='600'>";
$sad=$d11;}}$i++;
$cs11[$i]=$sad." ";
}
foreach ($cs11 as $dimz)
{
echo $dimz;
}
?>

Categories