Заменить URL-адреса в тексте HTML-ссылками

Вот дизайн: Например, я помещаю ссылку, такую ​​как

http://example.com

в текстовой области . Как заставить PHP определить, что это ссылка http:// а затем распечатать его как

 print "<a href='http://www.example.com'>http://www.example.com</a>"; 

Я помню, что делал что-то вроде этого, прежде чем, однако, это было не безупречное доказательство, что оно продолжало ломаться для сложных ссылок.

Еще одна хорошая идея – если у вас есть такая ссылка, как

http://example.com/test.php?val1=bla&val2blablabla%20bla%20bla.bl

исправить это, чтобы он

 print "<a href='http://example.com/test.php?val1=bla&val2=bla%20bla%20bla.bla'>"; print "http://example.com/test.php"; print "</a>"; 

Это одно из следующих соображений: stackoverflow также может, вероятно, использовать это: D

Есть идеи

Давайте рассмотрим требования. У вас есть пользовательский простой текст, который вы хотите отображать с гиперссылками.

  1. Префикс протокола http: // должен быть необязательным.
  2. Домены и IP-адреса должны быть приняты.
  3. Любой допустимый домен верхнего уровня должен быть принят, например .aero и .xn – jxalpdlp.
  4. Номера портов должны быть разрешены.
  5. URL-адреса должны быть разрешены в контексте обычных предложений. Например, в «Visit stackoverflow.com.» Последний период не является частью URL-адреса.
  6. Вероятно, вы также захотите разрешить URL-адрес «https: //», а также другие.
  7. Как всегда при отображении текста, предоставленного пользователем в HTML, вы хотите предотвратить межсайтовый скриптинг (XSS). Кроме того, вы хотите, чтобы амперсанды в URL-адресах были правильно экранированы как & amp ;.
  8. Вероятно, вам не нужна поддержка адресов IPv6.
  9. Изменить : Как отмечено в комментариях, поддержка адресов электронной почты – это, безусловно, плюс.
  10. Изменить : должен поддерживаться только обычный текстовый ввод – HTML-теги во входных данных не должны выполняться. (Версия Bitbucket поддерживает HTML-ввод.)

Изменить : проверить Bitbucket для последней версии, с поддержкой адресов электронной почты, аутентифицированных URL-адресов, URL-адресов в кавычках и круглых скобках, ввода HTML, а также обновленного списка TLD.

Сообщайте об ошибках и улучшениях, используя трекер Bitbucket . Им легче отслеживать этот путь (и не загромождать область комментариев).

Вот мой прием:

 <?php $text = <<<EOD Here are some URLs: stackoverflow.com/questions/1188129/pregreplace-to-detect-html-php Here's the answer: http://www.google.com/search?rls=en&q=42&ie=utf-8&oe=utf-8&hl=en. What was the question? A quick look at http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax is helpful. There is no place like 127.0.0.1! Except maybe http://news.bbc.co.uk/1/hi/england/surrey/8168892.stm? Ports: 192.168.0.1:8080, https://example.net:1234/. Beware of Greeks bringing internationalized top-level domains: xn--hxajbheg2az3al.xn--jxalpdlp. And remember.Nobody is perfect. <script>alert('Remember kids: Say no to XSS-attacks! Always HTML escape untrusted input!');</script> EOD; $rexProtocol = '(https?://)?'; $rexDomain = '((?:[-a-zA-Z0-9]{1,63}\.)+[-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})'; $rexPort = '(:[0-9]{1,5})?'; $rexPath = '(/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?'; $rexQuery = '(\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?'; $rexFragment = '(#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?'; // Solution 1: function callback($match) { // Prepend http:// if no protocol specified $completeUrl = $match[1] ? $match[0] : "http://{$match[0]}"; return '<a href="' . $completeUrl . '">' . $match[2] . $match[3] . $match[4] . '</a>'; } print "<pre>"; print preg_replace_callback("&\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))&", 'callback', htmlspecialchars($text)); print "</pre>"; . <?php $text = <<<EOD Here are some URLs: stackoverflow.com/questions/1188129/pregreplace-to-detect-html-php Here's the answer: http://www.google.com/search?rls=en&q=42&ie=utf-8&oe=utf-8&hl=en. What was the question? A quick look at http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax is helpful. There is no place like 127.0.0.1! Except maybe http://news.bbc.co.uk/1/hi/england/surrey/8168892.stm? Ports: 192.168.0.1:8080, https://example.net:1234/. Beware of Greeks bringing internationalized top-level domains: xn--hxajbheg2az3al.xn--jxalpdlp. And remember.Nobody is perfect. <script>alert('Remember kids: Say no to XSS-attacks! Always HTML escape untrusted input!');</script> EOD; $rexProtocol = '(https?://)?'; $rexDomain = '((?:[-a-zA-Z0-9]{1,63}\.)+[-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})'; $rexPort = '(:[0-9]{1,5})?'; $rexPath = '(/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?'; $rexQuery = '(\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?'; $rexFragment = '(#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?'; // Solution 1: function callback($match) { // Prepend http:// if no protocol specified $completeUrl = $match[1] ? $match[0] : "http://{$match[0]}"; return '<a href="' . $completeUrl . '">' . $match[2] . $match[3] . $match[4] . '</a>'; } print "<pre>"; print preg_replace_callback("&\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))&", 'callback', htmlspecialchars($text)); print "</pre>"; 
  • Для правильного выхода из <и & символов, я бросаю весь текст через htmlspecialchars перед обработкой. Это не идеально, поскольку html-экранирование может привести к неверному определению границ URL.
  • Как продемонстрировано «И помните. Никто не идеален». line (в котором mem.Nobody рассматривается как URL-адрес, из-за недостающего места), дальнейшая проверка допустимых доменов верхнего уровня может быть в порядке.

Изменить : Следующий код исправляет две вышеуказанные проблемы, но довольно немного более подробный, поскольку я более или менее повторно реализую preg_replace_callback с помощью preg_match .

 // Solution 2: $validTlds = array_fill_keys(explode(" ", ".aero .asia .biz .cat .com .coop .edu .gov .info .int .jobs .mil .mobi .museum .name .net .org .pro .tel .travel .ac .ad .ae .af .ag .ai .al .am .an .ao .aq .ar .as .at .au .aw .ax .az .ba .bb .bd .be .bf .bg .bh .bi .bj .bm .bn .bo .br .bs .bt .bv .bw .by .bz .ca .cc .cd .cf .cg .ch .ci .ck .cl .cm .cn .co .cr .cu .cv .cx .cy .cz .de .dj .dk .dm .do .dz .ec .ee .eg .er .es .et .eu .fi .fj .fk .fm .fo .fr .ga .gb .gd .ge .gf .gg .gh .gi .gl .gm .gn .gp .gq .gr .gs .gt .gu .gw .gy .hk .hm .hn .hr .ht .hu .id .ie .il .im .in .io .iq .ir .is .it .je .jm .jo .jp .ke .kg .kh .ki .km .kn .kp .kr .kw .ky .kz .la .lb .lc .li .lk .lr .ls .lt .lu .lv .ly .ma .mc .md .me .mg .mh .mk .ml .mm .mn .mo .mp .mq .mr .ms .mt .mu .mv .mw .mx .my .mz .na .nc .ne .nf .ng .ni .nl .no .np .nr .nu .nz .om .pa .pe .pf .pg .ph .pk .pl .pm .pn .pr .ps .pt .pw .py .qa .re .ro .rs .ru .rw .sa .sb .sc .sd .se .sg .sh .si .sj .sk .sl .sm .sn .so .sr .st .su .sv .sy .sz .tc .td .tf .tg .th .tj .tk .tl .tm .tn .to .tp .tr .tt .tv .tw .tz .ua .ug .uk .us .uy .uz .va .vc .ve .vg .vi .vn .vu .wf .ws .ye .yt .yu .za .zm .zw .xn--0zwm56d .xn--11b5bs3a9aj6g .xn--80akhbyknj4f .xn--9t4b11yi5a .xn--deba0ad .xn--g6w251d .xn--hgbk6aj7f53bba .xn--hlcj6aya9esc7a .xn--jxalpdlp .xn--kgbechtv .xn--zckzah .arpa"), true); $position = 0; while (preg_match("{\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))}", $text, &$match, PREG_OFFSET_CAPTURE, $position)) { list($url, $urlPosition) = $match[0]; // Print the text leading up to the URL. print(htmlspecialchars(substr($text, $position, $urlPosition - $position))); $domain = $match[2][0]; $port = $match[3][0]; $path = $match[4][0]; // Check if the TLD is valid - or that $domain is an IP address. $tld = strtolower(strrchr($domain, '.')); if (preg_match('{\.[0-9]{1,3}}', $tld) || isset($validTlds[$tld])) { // Prepend http:// if no protocol specified $completeUrl = $match[1][0] ? $url : "http://$url"; // Print the hyperlink. printf('<a href="%s">%s</a>', htmlspecialchars($completeUrl), htmlspecialchars("$domain$port$path")); } else { // Not a valid URL. print(htmlspecialchars($url)); } // Continue text parsing from after the URL. $position = $urlPosition + strlen($url); } // Print the remainder of the text. print(htmlspecialchars(substr($text, $position))); 

Вот что я нашел, что проверено и проверено

 function make_links_blank($text) { return preg_replace( array( '/(?(?=<a[^>]*>.+<\/a>) (?:<a[^>]*>.+<\/a>) | ([^="\']?)((?:https?|ftp|bf2|):\/\/[^<> \n\r]+) )/iex', '/<a([^>]*)target="?[^"\']+"?/i', '/<a([^>]+)>/i', '/(^|\s)(www.[^<> \n\r]+)/iex', '/(([_A-Za-z0-9-]+)(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-]+) (\\.[A-Za-z0-9-]+)*)/iex' ), array( "stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\">\\2</a>\\3':'\\0'))", '<a\\1', '<a\\1 target="_blank">', "stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\">\\2</a>\\3':'\\0'))", "stripslashes((strlen('\\2')>0?'<a href=\"mailto:\\0\">\\0</a>':'\\0'))" ), $text ); } . function make_links_blank($text) { return preg_replace( array( '/(?(?=<a[^>]*>.+<\/a>) (?:<a[^>]*>.+<\/a>) | ([^="\']?)((?:https?|ftp|bf2|):\/\/[^<> \n\r]+) )/iex', '/<a([^>]*)target="?[^"\']+"?/i', '/<a([^>]+)>/i', '/(^|\s)(www.[^<> \n\r]+)/iex', '/(([_A-Za-z0-9-]+)(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-]+) (\\.[A-Za-z0-9-]+)*)/iex' ), array( "stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\">\\2</a>\\3':'\\0'))", '<a\\1', '<a\\1 target="_blank">', "stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\">\\2</a>\\3':'\\0'))", "stripslashes((strlen('\\2')>0?'<a href=\"mailto:\\0\">\\0</a>':'\\0'))" ), $text ); } 

Меня устраивает. И он работает для писем и URL-адресов, извините, что ответил на мой собственный вопрос. 🙁

Но это единственное, что работает

Вот ссылка, где я ее нашел: http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_21878567.html

Зарядись, потому что это экспертная биржа.

Вы, парни, говорим о том, как продвигаться и сложный материал, который хорош для какой-то ситуации, но в основном нам нужно простое неосторожное решение. Как насчет этого?

 preg_replace('/(http[s]{0,1}\:\/\/\S{4,})\s{0,}/ims', '<a href="$1" target="_blank">$1</a> ', $text_msg); 

Просто попробуйте и дайте мне знать, какой сумасшедший URL-адрес он не удовлетворяет.

Вот код с использованием регулярных выражений в функции

 <?php //Function definations function MakeUrls($str) { $find=array('`((?:https?|ftp)://\S+[[:alnum:]]/?)`si','`((?<!//)(www\.\S+[[:alnum:]]/?))`si'); $replace=array('<a href="$1" target="_blank">$1</a>', '<a href="http://$1" target="_blank">$1</a>'); return preg_replace($find,$replace,$str); } //Function testing $str="www.cloudlibz.com"; $str=MakeUrls($str); echo $str; ?> , <?php //Function definations function MakeUrls($str) { $find=array('`((?:https?|ftp)://\S+[[:alnum:]]/?)`si','`((?<!//)(www\.\S+[[:alnum:]]/?))`si'); $replace=array('<a href="$1" target="_blank">$1</a>', '<a href="http://$1" target="_blank">$1</a>'); return preg_replace($find,$replace,$str); } //Function testing $str="www.cloudlibz.com"; $str=MakeUrls($str); echo $str; ?> , <?php //Function definations function MakeUrls($str) { $find=array('`((?:https?|ftp)://\S+[[:alnum:]]/?)`si','`((?<!//)(www\.\S+[[:alnum:]]/?))`si'); $replace=array('<a href="$1" target="_blank">$1</a>', '<a href="http://$1" target="_blank">$1</a>'); return preg_replace($find,$replace,$str); } //Function testing $str="www.cloudlibz.com"; $str=MakeUrls($str); echo $str; ?> 

Я использую эту функцию, она работает для меня

 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].'<a href="http'. $matches['4'][$i].'://'. $matches['5'][$i]. $matches['6'][$i].'"'.$pop.'>http'. $matches['4'][$i].'://'. $matches['5'][$i]. $matches['6'][$i].'</a>'. $period, $str); }//end for }//end if return $str; }//end AutoLinkUrls 

Все кредиты предоставлены – http://snipplr.com/view/68586/

Наслаждайтесь!

Этот RegEx должен соответствовать любой ссылке, за исключением этих новых доменов верхнего уровня 3+.

  {
   \\ Ь
   # Совместить ведущую часть (proto: // имя хоста или просто имя хоста)
   (
     # http: // или https: // ведущая часть
     (HTTPS): // [- \\ ш] + (. \\ \\ ш [- \\ ш] *) +
   |
     # или, попробуйте найти имя хоста с более конкретным подвыражением
     (? i: [a-z0-9] (?: [- a-z0-9] * [a-z0-9])? \\.) + # поддомены
     # Теперь завершение .com и т. Д. Для этого требуется строчный регистр
     (? -i: com \\ b
         |  Edu \\ Ь
         |  BiZ \\ Ь
         |  г \\ Ь
         |  в (?: t | fo) \\ b # .int или .info
         |  Миля \\ Ь
         |  Чистая \\ Ь
         |  орг \\ Ь
         |  [az] [az] \\. [az] [az] \\ b # двухбуквенный код страны
     )
   )

   # Разрешить дополнительный номер порта
   (: \\ d +)?

   # Остальная часть URL является необязательной и начинается с /
   (
     /
     # Остальные эвристики для того, что, кажется, хорошо работает
     [.!? ^; "\\ () \ [\] \ {\} \ s \ x7F - \\ XFF] *
     (
       [.!,?] + [^.!,?; "\\ '() \\ [\\] \ {\\} \ s \\ x7F - \\ xFF] +
     ) *
   )?
 } IX

Это не написано мной, я не совсем уверен, откуда у меня это получается, извините, что я не могу отдать должное …

это должно получить ваши адреса электронной почты:

 $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 ) 

Я знаю, что этот ответ принят и этот вопрос довольно старый, но он может быть полезен другим людям, которые ищут другие реализации.

Это измененная версия кода, опубликованная: Angel.King.47 от 27 июля 2009 года:

 $text = preg_replace( array( '/(^|\s|>)(www.[^<> \n\r]+)/iex', '/(^|\s|>)([_A-Za-z0-9-]+(\\.[A-Za-z]{2,3})?\\.[A-Za-z]{2,4}\\/[^<> \n\r]+)/iex', '/(?(?=<a[^>]*>.+<\/a>)(?:<a[^>]*>.+<\/a>)|([^="\']?)((?:https?):\/\/([^<> \n\r]+)))/iex' ), array( "stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>&nbsp;\\3':'\\0'))", "stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>&nbsp;\\4':'\\0'))", "stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\" target=\"_blank\">\\3</a>&nbsp;':'\\0'))", ), $text ); 

Изменения:

  • Я удалил правила № 2 и № 3 (я не уверен, в каких ситуациях это полезно).
  • Удаленный синтаксический анализ электронной почты, поскольку мне это действительно не нужно.
  • Я добавил еще одно правило, которое позволяет распознавать URL-адреса в форме: [domain] / * (без www). Например: «example.com/faq/» (несколько tld: домен. {2-3}. {2-4} /)
  • При анализе строк, начинающихся с «http: //», он удаляет их из метки ссылки.
  • Добавлен «target = '_ blank» для всех ссылок.
  • Urls можно указать сразу после любого (?) Тега. Например: <b> http://www.example.com </ b>

Как заявила «Søren Løvborg», эта функция не удаляет URL-адреса. Я попробовал его / ее класс, но он просто не работал, как я ожидал (если вы не доверяете своим пользователям, а затем сначала попробуйте его / ее код).

Как я уже упоминал в одном из комментариев выше моего VPS, на котором запущен php 7, начали выдавать предупреждения Warning: preg_replace (): Модификатор / e больше не поддерживается, вместо этого используйте preg_replace_callback . Буфер после замены был пустым / ложным.

Я переписал код и внес некоторые улучшения. Если вы считаете, что вы должны быть в разделе автора, не стесняйтесь редактировать комментарий выше имени функции make_links_blank. Я намеренно не использую закрытие php?>, Чтобы избежать вставки пробелов в выходной файл.

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

Что-то вроде:

 <?php if(preg_match('@^http://(.*)\s|$@g', $textarea_url, $matches)) { echo '<a href=http://", $matches[1], '">', $matches[1], '</a>'; } ?> 

Этот class изменяет URL-адреса в тексте и сохраняет домашний URL-адрес таким, какой он есть. Надеюсь, это поможет и сэкономит вам время. Наслаждайтесь.

 class RegClass { function preg_callback_url($matches) { //var_dump($matches); //Get the matched URL text <a>text</a> $text = $matches[2]; //Get the matched URL link <a href ="http://www.test.com">text</a> $url = $matches[1]; if($url=='href ="http://www.test.com"'){ //replace all a tag as it is return '<a href='.$url.' rel="nofollow"> '.$text.' </a>'; }else{ //replace all a tag to text return " $text " ; } } function ParseText($text){ $text = preg_replace( "/www\./", "http://www.", $text ); $regex ="/http:\/\/http:\/\/www\./" $text = preg_replace( $regex, "http://www.", $text ); $regex2 = "/https:\/\/http:\/\/www\./"; $text = preg_replace( $regex2, "https://www.", $text ); return preg_replace_callback('/<a\s(.+?)>(.+?)<\/a>/is', array( &$this, 'preg_callback_url'), $text); } } $regexp = new RegClass(); echo $regexp->ParseText($text); 

Если вы хотите доверять IANA, вы можете использовать свой текущий список поддерживаемых оффлайн поддерживаемых TLD, например:

  $validTLDs = explode("\n", file_get_contents('http://data.iana.org/TLD/tlds-alpha-by-domain.txt')); //get the official list of valid tlds array_shift($validTLDs); //throw away first line containing meta data array_pop($validTLDs); //throw away last element which is empty 

Делает решение Søren Løvborg №2 немного менее подробным и избавляет вас от хлопот по обновлению списка, в наши дни новые tlds выбрасываются так небрежно;)

Это сработало для меня (превратил один из ответов в функцию PHP)

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

Это должно получить ваш твиттер, не касаясь вашего письма / (? <= ^ | (? <= [^ A-zA-Z0-9- .])) @ ([A-Za-z] + [A-Za -z0-9 ] +) / i

Хотя совпадение полной спецификации URL затруднено, вот регулярное выражение, которое обычно делает хорошую работу:

 ([\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[az]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?) 

Однако, чтобы использовать это в preg_replace, вам нужно избежать этого. Таким образом:

 $pattern = "/([\\w-]+(\\.[\\w-]+)*@([a-z0-9-]+(\\.[a-z0-9-]+)*?\\.[az]{2,6}|(\\d{1,3}\\.){3}\\d{1,3})(:\\d{4})?)/"; $replaced_texttext = preg_replace($pattern, '<a href="$0" title="$0">$0</a>', $text);