Here is a design though: For example is I put a link such as
http://example.com
in textarea. How do I get PHP t
While matching the full url spec is difficult, here's a regular expression that generally does a good job:
([\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?)
To use this in preg_replace, however, you need to escape it. As so:
$pattern = "/([\\w-]+(\\.[\\w-]+)*@([a-z0-9-]+(\\.[a-z0-9-]+)*?\\.[a-z]{2,6}|(\\d{1,3}\\.){3}\\d{1,3})(:\\d{4})?)/";
$replaced_texttext = preg_replace($pattern, '<a href="$0" title="$0">$0</a>', $text);
As I mentioned in one of the comments above my VPS, which is running php 7, started emitting warnings Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead. The buffer after the replacement was empty/false.
I have rewritten the code and made some improvements. If you think that you should be in the author section feel free to edit the comment above the function make_links_blank name. I am intentionally not using the closing php ?> to avoid inserting whitespace in the output.
<?php
class App_Updater_String_Util {
public static function get_default_link_attribs( $regex_matches = [] ) {
$t = ' target="_blank" ';
return $t;
}
/**
* App_Updater_String_Util::set_protocol();
* @param string $link
* @return string
*/
public static function set_protocol( $link ) {
if ( ! preg_match( '#^https?#si', $link ) ) {
$link = 'http://' . $link;
}
return $link;
}
/**
* Goes through text and makes whatever text that look like a link an html link
* which opens in a new tab/window (by adding target attribute).
*
* Usage: App_Updater_String_Util::make_links_blank( $text );
*
* @param str $text
* @return str
* @see http://stackoverflow.com/questions/1188129/replace-urls-in-text-with-html-links
* @author Angel.King.47 | http://dashee.co.uk
* @author Svetoslav Marinov (Slavi) | http://orbisius.com
*/
public static function make_links_blank( $text ) {
$patterns = [
'#(?(?=<a[^>]*>.+?<\/a>)
(?:<a[^>]*>.+<\/a>)
|
([^="\']?)((?:https?|ftp):\/\/[^<> \n\r]+)
)#six' => function ( $matches ) {
$r1 = empty( $matches[1] ) ? '' : $matches[1];
$r2 = empty( $matches[2] ) ? '' : $matches[2];
$r3 = empty( $matches[3] ) ? '' : $matches[3];
$r2 = empty( $r2 ) ? '' : App_Updater_String_Util::set_protocol( $r2 );
$res = ! empty( $r2 ) ? "$r1<a href=\"$r2\">$r2</a>$r3" : $matches[0];
$res = stripslashes( $res );
return $res;
},
'#(^|\s)((?:https?://|www\.|https?://www\.)[^<>\ \n\r]+)#six' => function ( $matches ) {
$r1 = empty( $matches[1] ) ? '' : $matches[1];
$r2 = empty( $matches[2] ) ? '' : $matches[2];
$r3 = empty( $matches[3] ) ? '' : $matches[3];
$r2 = ! empty( $r2 ) ? App_Updater_String_Util::set_protocol( $r2 ) : '';
$res = ! empty( $r2 ) ? "$r1<a href=\"$r2\">$r2</a>$r3" : $matches[0];
$res = stripslashes( $res );
return $res;
},
// Remove any target attribs (if any)
'#<a([^>]*)target="?[^"\']+"?#si' => '<a\\1',
// Put the target attrib
'#<a([^>]+)>#si' => '<a\\1 target="_blank">',
// Make emails clickable Mailto links
'/(([\w\-]+)(\\.[\w\-]+)*@([\w\-]+)
(\\.[\w\-]+)*)/six' => function ( $matches ) {
$r = $matches[0];
$res = ! empty( $r ) ? "<a href=\"mailto:$r\">$r</a>" : $r;
$res = stripslashes( $res );
return $res;
},
];
foreach ( $patterns as $regex => $callback_or_replace ) {
if ( is_callable( $callback_or_replace ) ) {
$text = preg_replace_callback( $regex, $callback_or_replace, $text );
} else {
$text = preg_replace( $regex, $callback_or_replace, $text );
}
}
return $text;
}
}
this should get you email addresses:
$string = "bah bah steve@gmail.com foo";
$match = preg_match('/[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)*\@[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)+/', $string, $array);
print_r($array);
// outputs:
Array
(
[0] => steve@gmail.com
)
This RegEx should match any link except for these new 3+ character toplevel domains...
{ \\b # Match the leading part (proto://hostname, or just hostname) ( # http://, or https:// leading part (https?)://[-\\w]+(\\.\\w[-\\w]*)+ | # or, try to find a hostname with more specific sub-expression (?i: [a-z0-9] (?:[-a-z0-9]*[a-z0-9])? \\. )+ # sub domains # Now ending .com, etc. For these, require lowercase (?-i: com\\b | edu\\b | biz\\b | gov\\b | in(?:t|fo)\\b # .int or .info | mil\\b | net\\b | org\\b | [a-z][a-z]\\.[a-z][a-z]\\b # two-letter country code ) ) # Allow an optional port number ( : \\d+ )? # The rest of the URL is optional, and begins with / ( / # The rest are heuristics for what seems to work well [^.!,?;"\\'()\[\]\{\}\s\x7F-\\xFF]* ( [.!,?]+ [^.!,?;"\\'()\\[\\]\{\\}\s\\x7F-\\xFF]+ )* )? }ix
It's not written by me, I'm not quite sure where I got it from, sorry that I can give no credit...
This worked for me (turned one of the answers into a PHP function)
function make_urls_from_text ($text){
return preg_replace('/(http[s]{0,1}\:\/\/\S{4,})\s{0,}/ims', '<a href="$1" target="_blank">$1 </a>', $text);
}