2012-06-03 8 views
8

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

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

Вот образец, который я сейчас использую:

$pattern = "/(((http[s]?:\/\/)|(www\.))(([a-z][-a-z0-9]+\.)?[a-z][-a-z0-9]+\.[a-z]+(\.[a-z]{2,2})?)\/?[a-z0-9.,_\/~#&=;%+?-]+[a-z0-9\/#=?]{1,1})/is"; 

Однако здесь некоторые ссылки, которые я нашел, что эта картина не соответствует:

  • www.oakvilletransit.ca - Не уверен, , но при условии, что он не соответствует из-за двухбуквенного кода страны
  • www.grt.ca - Еще один домен с доменом .ca, который не работает
  • Несколько других .ca a ddresses
  • freepublictransports.com - Адреса без www. или http: // перед ними. Я бы хотел, чтобы они работали.
  • www.222tips.com - Предполагая, что это не соответствует из-за номеров в начале адреса.

Кто-нибудь знает, как я могу изменить этот шаблон регулярного выражения, чтобы он соответствовал этим случаям?

EDIT - Он также должен соответствовать URL-адресам, которые могут иметь период в конце. Если URL-адрес является последней частью предложения, в конце может быть период, который не должен быть включен в фактическую ссылку. В настоящее время этот шаблон учитывает это также.

РЕДАКТИРОВАТЬ 2 - Я использую шаблон, как это:

$pattern = "/((http|https):\/\/)?([a-z0-9-]+\.)?[a-z][a-z0-9-]+(\.[a-z]{2,6}){1,3}(\/[a-z0-9.,_\/~#&=;%+?-]*)?/is"; 
    $string = preg_replace($pattern, " <a target='_blank' href='$1'>$1</a>", $string); 
    // fix URLs without protocols 
    $string = preg_replace("/href='www/", "href='http://www", $string); 
    return $string; 
+0

Regex совет: '[s]' не надо?. Просто используйте 's?'. – Ryan

+0

Регулярное выражение: '{1,1}' не имеет никакого смысла. И '{2,2}'. – Ryan

+0

Хорошо, я нашел этот код в другом вопросе. Итак, измените [s]? к s? и удаление {1,1} и {2,2} не должно иметь значения? –

ответ

5

Ниже регулярное выражение будет соответствовать URL-адресов:

  • (Необязательно) С http:// или https://
  • (Необязательно) С субдоменом (www.example.com, help.example.com и т. Д.)
  • С 1-3 расширений домена, каждый из которых должен быть 2-6 символами (www.example.com.gu, www.example.com.au.museum и т.д.)
  • (по желанию) с косыми чертами в конце
  • (Необязательно) с действительными символами после косых черт

/i в конце делает случай нечувствительный.

/((http|https):\/\/)?([a-z0-9-]+\.)?[a-z0-9-]+(\.[a-z]{2,6}){1,3}(\/[a-z0-9.,_\/~#&=;%+?-]*)?/is

Edit: Это не соответствует ни одному «висит» периоды в конце (например, в конце предложения), потому что это не является частью URL, и не должны быть включены в href атрибут вашей ссылки.

Edit 2: В своем первом preg_replace() измените $1 на $0. Это будет вставлять всю согласованную строку вместо одной ее части.

Edit 3: (Update 2) Вот лучший способ вы можете проверить на http:// или https:// в начале:

preg_replace("/href='[^h][^t][^t][^p][^s]?[^:]/", "/href='http:\/\/", $string); 
+0

((http | https): //) должно быть ((http | https): \/\ /) Я начал использовать # вместо «/» в качестве разделителя при работе с URL-адресами, t должны уйти от косых черт. И/i делает регистр случайным. – Sp4cecat

+1

Derp. Сделал это на regexbuddy, забыл избежать этих двух. Обновленный ответ, спасибо. __Edit: __ Я никогда не знал, что вы можете использовать разные символы для разделителей! Это здорово узнать, спасибо. – Litty

+0

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

3

У меня были проблемы со всеми вышеизложенными примерами.

Вот один, который работает:

function autolink($string){ 
     $string= preg_replace("#http://([\S]+?)#Uis", '<a href="http://\\1">\\1</a>', $string); 
     return $string; 
} 
Смежные вопросы