Java: замена текстового URL-адреса кликабельной HTML-ссылкой

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

Моя начальная строка выглядит так:

"hello, i'm some text with an url like http://www.the-url.com/ and I need to have an hypertext link !"

Я хочу получить строку, похожую на:

"hello, i'm some text with an url like <a href="http://www.the-url.com/">http://www.the-url.com/</a> and I need to have an hypertext link !"

Я могу поймать URL с помощью этой строки кода:

String withUrlString = myString.replaceAll(".*://[^<>[:space:]]+[[:alnum:]/]", "<a href=\"null\">HereWasAnURL</a>");

Возможно, выражение регулярного выражения нуждается в некоторой корректировке, но оно работает нормально, нужно проверить в дальнейшем.

Итак, вопрос в том, как сохранить выражение, перехваченное регулярным выражением, и просто добавить то, что необходимо для создания ссылки: пойманная строка

Заранее спасибо за ваш интерес и ответы!


person Dough    schedule 15.12.2009    source источник
comment
Хотя приведенные ниже ответы должны вам помочь, я предлагаю вам взглянуть на регулярное выражение Джона Грубера для захвата URL-адресов во всех формах, которые встречаются в дикой природе: daringfireball.net/2009/11/liberal_regex_for_matching_urls   -  person FRotthowe    schedule 15.12.2009


Ответы (6)


Попробуй использовать:

myString.replaceAll("(.*://[^<>[:space:]]+[[:alnum:]/])", "<a href=\"$1\">HereWasAnURL</a>");

Я не проверял ваше регулярное выражение.

С помощью () вы можете создавать группы. $1 указывает индекс группы. $1 заменит URL.

Я задал похожий вопрос: мой вопрос
Некоторые примеры: Захват текста в группе в регулярном выражении

person Martijn Courteaux    schedule 15.12.2009
comment
Это не работает для нескольких ссылок в тексте, потому что .* занимает слишком много места. - person Sonson123; 28.09.2015

public static String textToHtmlConvertingURLsToLinks(String text) {
    if (text == null) {
        return text;
    }

    String escapedText = HtmlUtils.htmlEscape(text);

    return escapedText.replaceAll("(\\A|\\s)((http|https|ftp|mailto):\\S+)(\\s|\\z)",
        "$1<a href=\"$2\">$2</a>$4");
}

Там могут быть лучшие REGEX, но это помогает, если после конца URL-адреса есть пробел или URL-адрес находится в конце текста. Эта конкретная реализация также использует org.springframework.web.util.HtmlUtils для экранирования любого другого HTML, который мог быть введен.

person Paul Croarkin    schedule 10.11.2010
comment
Не работает для двух ссылок, разделенных одним пробелом. - person Sonson123; 28.09.2015

Всем, кто ищет более надежное решение, я могу предложить текстовые библиотеки Twitter.

Замена URL-адресов этой библиотекой работает следующим образом:

new Autolink().autolink(plainText) 
person Sonson123    schedule 28.09.2015
comment
URL-адрес должен быть хорошо отформатирован. не удалось обнаружить: www.example.com (http:// отсутствует). :( - person redochka; 29.11.2017

Приведенный ниже код заменяет ссылки, начинающиеся с «http» или «https», ссылками, начинающимися только с «www». и, наконец, заменяет также ссылки на электронную почту.

  Pattern httpLinkPattern = Pattern.compile("(http[s]?)://(www\\.)?([\\S&&[^.@]]+)(\\.[\\S&&[^@]]+)");

  Pattern wwwLinkPattern = Pattern.compile("(?<!http[s]?://)(www\\.+)([\\S&&[^.@]]+)(\\.[\\S&&[^@]]+)");

  Pattern mailAddressPattern = Pattern.compile("[\\S&&[^@]]+@([\\S&&[^.@]]+)(\\.[\\S&&[^@]]+)");

    String textWithHttpLinksEnabled = 
  "ajdhkas www.dasda.pl/asdsad?asd=sd www.absda.pl [email protected] klajdld http://dsds.pl httpsda http://www.onet.pl https://www.onsdas.plad/dasda";

    if (Objects.nonNull(textWithHttpLinksEnabled)) {

      Matcher httpLinksMatcher = httpLinkPattern.matcher(textWithHttpLinksEnabled);
      textWithHttpLinksEnabled = httpLinksMatcher.replaceAll("<a href=\"$0\" target=\"_blank\">$0</a>");

      final Matcher wwwLinksMatcher = wwwLinkPattern.matcher(textWithHttpLinksEnabled);
      textWithHttpLinksEnabled = wwwLinksMatcher.replaceAll("<a href=\"http://$0\" target=\"_blank\">$0</a>");

      final Matcher mailLinksMatcher = mailAddressPattern.matcher(textWithHttpLinksEnabled);
      textWithHttpLinksEnabled = mailLinksMatcher.replaceAll("<a href=\"mailto:$0\">$0</a>");

      System.out.println(textWithHttpLinksEnabled);
    }

Отпечатки:

ajdhkas <a href="http://www.dasda.pl/asdsad?asd=sd" target="_blank">www.dasda.pl/asdsad?asd=sd</a> <a href="http://www.absda.pl" target="_blank">www.absda.pl</a> <a href="mailto:[email protected]">[email protected]</a> klajdld <a href="http://dsds.pl" target="_blank">http://dsds.pl</a> httpsda <a href="http://www.onet.pl" target="_blank">http://www.onet.pl</a> <a href="https://www.onsdas.plad/dasda" target="_blank">https://www.onsdas.plad/dasda</a>
person walkeros    schedule 14.02.2017

Предполагая, что ваше регулярное выражение работает для получения правильной информации, вы можете использовать обратные ссылки в своей замене. См. руководство по регулярному выражению Java.

В этом случае вы бы сделали

myString.replaceAll(....., "<a href=\"\1\">\1</a>")
person Matt    schedule 15.12.2009

В случае многострочного текста вы можете использовать это:

text.replaceAll("(\\s|\\^|\\A)((http|https|ftp|mailto):\\S+)(\\s|\\$|\\z)",
        "$1<a href='$2'>$2</a>$4");

И вот полный пример моего кода, где мне нужно показать сообщения пользователя с URL-адресами:

private static final Pattern urlPattern = Pattern.compile(
        "(\\s|\\^|\\A)((http|https|ftp|mailto):\\S+)(\\s|\\$|\\z)");


String userText = ""; // user content from db
String replacedValue = HtmlUtils.htmlEscape(userText);
replacedValue = urlPattern.matcher(replacedValue).replaceAll("$1<a href=\"$2\">$2</a>$4");
replacedValue = StringUtils.replace(replacedValue, "\n", "<br>");
System.out.println(replacedValue);
person alaster    schedule 06.01.2017