Check if a string had been hyperlinked - php

What regular expression should I use to detect is the text I want to hyperlink had been already hyperlinked.
Example:
I use
$text = preg_replace('/((http)+(s)?:\/\/[^<>\s]+)/i', '\\0', $text);
to link regular URL, and
$text = preg_replace('/[#]+([A-Za-z_0-9]+)/', '#\\1', $text);
to link Twitter handle.
I want to detect whether or not the text I'm going to hyperlink had been wrapped in already.

Maybe not an answer but another possible solution; You could also search to see if the starting a element exists
$text = 'here';
if (gettype(strpos($text, "<a")) == "integer"){
//<a start tag was found
};
or just strip all tags regardless and build the link anyway
$text = 'here';
echo '' . strip_tags($text) . '';

Simple, replace the regular URLs first, as it won't affect anything starting with an # cause no URL starts with an #. Then replace the twitter handles.
That way you don't need to detect if it's been hyperlinked already.

if (strpos($str, '<a ') !== FALSE) echo 'ok';
else echo 'error';

$html = 'Stephen Ou';
$str = 'Stephen Ou';
if (strlen(str_replace($str, '', $html)) !== strlen($html)) {
echo 'I got a feeling';
}

Related

PHP preg_replace: Replace all anchor tags in text with their href value with Regex

I want to replace all anchor tags within a text with their href value, but my pattern does not work right.
$str = 'This is a text with multiple anchor tags. This is the first one: Link 1 and this one the second: Link 2 after that a lot of other text. And here the 3rd one: Link 3 Some other text.';
$test = preg_replace("/<a\s.+href=['|\"]([^\"\']*)['|\"].*>[^<]*<\/a>/i",'\1', $str);
echo $test;
At the end the text should look like this:
This is a text with multiple anchor tags. This is the first one: https://www.link1.com/ and this one the second: https://www.link2.com/ after that a lot of other text. And here the 3rd one: https://www.link3.com/ Some other text.
Thank you very much!
Just don't.
Use a parser instead.
$dom = new DOMDocument();
// since you have a fragment, wrap it in a <body>
$dom->loadHTML("<body>".$str."</body>");
$links = $dom->getElementsByTagName("a");
while($link = $links[0]) {
$link->parentNode->insertBefore(new DOMText($link->getAttribute("href")),$link);
$link->parentNode->removeChild($link);
}
$result = $dom->saveHTML($dom->getElementsByTagName("body")[0]);
// remove <body>..</body> wrapper
$output = substr($result, strlen("<body>"), -strlen("</body>"));
Demo on 3v4l
In case you're still set on regex, this should work:
preg_replace("/<a\s+href=['\"]([^'\"]+)['\"][^\>]*>[^<]+<\/a>/i",'$1', $str);
But you're probably better off with a solution like what Andreas posted.
FYI: the reason your previous regex didn't work was this little number:
.*>
Because . selects everything you ended up matching everything past the url to be replaced; all the way to the end. This is why it appeared to only select and replace the first anchor tag it found and cut off the rest.
Changing that to
[^\>]*
Ensures that this particular selection is constrained to only the portion of the string which exists between the url and the ending bracket of the a tag.
Simpler perhaps not, but safer is to loop the string with strpos to find and cut the string and remove the html.
$str = 'This is a text with multiple anchor tags. This is the first one: <a class="funky-style" href="https://www.link1.com/" title="Link 1">Link 1</a> and this one the second: Link 2 after that a lot of other text. And here the 3rd one: Link 3 Some other text.';
$pos = strpos($str, '<a');
while($pos !== false){
// Find start of html and remove up to link (<a href=")
$str = substr($str, 0, $pos) . substr($str, strpos($str, 'href="', $pos)+6);
// Find end of link and remove that.(" title="Link 1">Link 1</a>)
$str = substr($str, 0, strpos($str,'"', $pos)) . substr($str, strpos($str, '</a>', $pos)+4);
// Find next link if possible
$pos = strpos($str, '<a');
}
echo $str;
https://3v4l.org/vdN7E
Edited to handle different order of a a-tag.
If you want to replace a tags with href values you can do:
$post = preg_replace("/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/","$1",$post);
If you want to replace with text values:
$post = preg_replace("/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/","$2",$post);

How to find, make link and shorten url text in text block with PHP

So I currently have this...
<?php
$textblockwithformatedlinkstoecho = preg_replace('!(((f|ht)tp(s)?://)[-a-zA-
Zа-яА-Я()0-9#:%_+.~#?&;//=]+)!i', '$1',
$origtextwithlinks);
echo $textblockwithformatedlinkstoecho;
?>
But, I would like to also shorten the clickable link to around 15 chars in length...
Example input text
I recommend you visit http://www.example.com/folder1/folder2/page3.html?
longtext=ugsdfhsglshghsdghlsg8ysd87t8sdts8dtsdtygs9ysd908yfsd0fyu for more
information.
Required output text
I recommend you visit example.com/fol... for more information.
You can use preg_replace_callback() to manipulate the matches.
Example:
$text = "I recommend you visit http://www.example.com/folder1/folder2/page3.html?longtext=ugsdfhsglshghsdghlsg8ys\d87t8sdts8\dtsdtygs9ysd908yfsd0fyu for more information.";
$fixed = preg_replace_callback(
'!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9#:%_+.~#?&;//=]+)!i',
function($matches) {
// Get the fully matched url
$url = $matches[0];
// Do some magic for the link text, like only show the first 15 characters
$text = strlen($url) > 15
? substr($url, 0, 15) . '...'
: $url;
// Return the new html link
return '' . $text . '';
},
$text
);
echo $fixed;
You probably need to modify your regex though, since it doesn't match the \-characters you have in the query string in the url.

replace link with another

I'm struggling on replacing text in each link.
$reg_ex = "/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
$text = '<br /><p>this is a content with a link we are supposed to click</p><p>another - this is a content with a link we are supposed to click</p><p>another - this is a content with a link we are supposed to click</p>';
if(preg_match_all($reg_ex, $text, $urls))
{
foreach($urls[0] as $url)
{
echo $replace = str_replace($url,'http://www.sometext'.$url, $text);
}
}
From the code above, I'm getting 3x the same text, and the links are changed one by one: everytime is replaced only one link - because I use foreach, I know.
But I don't know how to replace them all at once.
Your help would be great!
You don't use regexes on html. use DOM instead. That being said, your bug is here:
$replace = str_replace(...., $text);
^^^^^^^^--- ^^^^^---
you never update $text, so you continually trash the replacement on every iteration of the loop. You probably want
$text = str_replace(...., $text);
instead, so the changes "propagate"
If you want the final variable to contain all replacements change it so something like this...
You basically are not passing the replaced string back into the "subject". I assume that is what you are expecting since it's a bit difficult to understand the question.
$reg_ex = "/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
$text = '<br /><p>this is a content with a link we are supposed to click</p><p>another - this is a content with a link we are supposed to click</p><p>another - this is a content with a link we are supposed to click</p>';
if(preg_match_all($reg_ex, $text, $urls))
{
$replace = $text;
foreach($urls[0] as $url) {
$replace = str_replace($url,'http://www.sometext'.$url, $replace);
}
echo $replace;
}

How do I auto convert an url into a hyper link in PHP?

I have a script that outputs status updates and I need to write a script that automatically changes something like www.example.com into a hyper link in a chunk of text like Twitter and Facebook do. What functions can I use for this in PHP? If you know a tutorial please post it.
$string = " fasfasd http://webarto.com fasfsafa";
echo preg_replace("#http://([\S]+?)#Uis", '<a rel="nofollow" href="http://\\1">\\1</a>', $string);
Output:
fasfasd <a rel="nofollow" href="http://webarto.com">webarto.com</a> fasfsafa
You can use a regex to replace the url with a link. Look at the answers on this thread: PHP - Add link to a URL in a string.
Great solution!
I wanted to auto-link web links and also to truncate the displayed URL text, because long URLs were breaking out of the layout on some platforms.
After much fiddling around with regex, I realised the solution is actually CSS - this site gives a simple solution using CSS white-space.
Here is the working Function
function AutoLinkUrls($str,$popup = FALSE){
if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches)){
$pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
for ($i = 0; $i < count($matches['0']); $i++){
$period = '';
if (preg_match("|\.$|", $matches['6'][$i])){
$period = '.';
$matches['6'][$i] = substr($matches['6'][$i], 0, -1);
}
$str = str_replace($matches['0'][$i],
$matches['1'][$i].'</xmp><a href="http'.
$matches['4'][$i].'://'.
$matches['5'][$i].
$matches['6'][$i].'"'.$pop.'>http'.
$matches['4'][$i].'://'.
$matches['5'][$i].
$matches['6'][$i].'</a><xmp>'.
$period, $str);
}//end for
}//end if
return $str; }

replace any url's within a string of text, to clickable links with php

Say i have a string of text such as
$text = "Hello world, be sure to visit http://whatever.com today";
how can i (probably using regex) insert the anchor tags for the link (showing the link itself as the link text) ?
You can use regexp to do this:
$html_links = preg_replace('"\b(https?://\S+)"', '$1', $text);
I write this function.
It replaces all the links in a string. Links can be in the following formats :
www.example.com
http://example.com
https://example.com
example.fr
The second argument is the target for the link ('_blank', '_top'... can be set to false).
Hope it helps...
public static function makeLinks($str, $target='_blank')
{
if ($target)
{
$target = ' target="'.$target.'"';
}
else
{
$target = '';
}
// find and replace link
$str = preg_replace('#((https?://)?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.~]*(\?\S+)?)?)*)#', '<a href="$1" '.$target.'>$1</a>', $str);
// add "http://" if not set
$str = preg_replace('/<a\s[^>]*href\s*=\s*"((?!https?:\/\/)[^"]*)"[^>]*>/i', '<a href="http://$1" '.$target.'>', $str);
return $str;
}
Edit: Added tilde to make urls work better https://regexr.com/5m16v

Categories