Найти и обернуть ссылки в тексте

200
21 февраля 2018, 07:50

Делаю чат на C#. Встал вопрос подсветки ссылок в чате.

Нужна функция куда можно передать String (который имеет множество ссылок вида ru.stackoverflow.com) и на выходе получить текст с ссылками в вида

<a href="ru.stackoverflow.com">ru.stackoverflow.com</a>

Т.е. нужна возможность подсвечивать ссылки, а не выдирать Url как в подобных примерах.

Прототип функции, которую надо сделать.

String ParsingLink(String text)
{
    //.....
    return text;
}

Кто может поделиться работающим примером?

Желательно использовать Regex.

Answer 1

Накидал на C# используя предыдущий пример на PHP.

public String ParsingLink(String source)
{
    Regex regExHttpLinks = new Regex(@"(?<=\()\b(https?://|www\.)[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|](?=\))|(?<=(?<wrap>[=~|_#]))\b(https?://|www\.)[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|](?=\k<wrap>)|\b(https?://|www\.)[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    if (String.IsNullOrEmpty(source))
        return source;
    var periodReplacement = "[[[replace:period]]]";
    source = Regex.Replace(source, @"(?<=\d)\.(?=\d)", periodReplacement);
    var linkMatches = regExHttpLinks.Matches(source);
    foreach (Match match in linkMatches)
    {
        var m = match.ToString();
        String s = (m.Contains("://")) ? m : "http://" + m;
        source = source.Replace(m,
          String.Format("<a href=\"{0}\" rel=\"nofollow\" title=\"{0}\">{1}</a>",
          s.Replace(".", periodReplacement).ToLower(),
          m.Replace(".", periodReplacement)));
    }
    source = source.Replace(periodReplacement, ".");
    return source;
}
Answer 2

Немного не понятно с подсветкой, но вот функция, которую вы просили

 string Find(string inputString)
        {
            Regex regex = new Regex(@"(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?");
            MatchCollection matches = regex.Matches(inputString);
            if (matches.Count > 0)
            {
                foreach (Match match in matches)
                    inputString = inputString.Replace(match.Value, "<a href=\""+match.Value+"\">"+new Uri(match.Value).Host+ "</a>");
            }

            return inputString;
        }

На входе

text1 https://ru.stackoverflow.com/questions/787166/%D0%9F%D0%B0%D1%80%D1%81%D0%B8%D0%BD%D0%B3-%D1%81%D1%81%D1%8B%D0%BB%D0%BE%D0%BA-%D0%B2-%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%B5-c#787166 text2 https://vk.com/ text3

На выходе

text1 <a href="https://ru.stackoverflow.com/questions/787166/%D0%9F%D0%B0%D1%80%D1%81%D0%B8%D0%BD%D0%B3-%D1%81%D1%81%D1%8B%D0%BB%D0%BE%D0%BA-%D0%B2-%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%B5-c#787166">ru.stackoverflow.com</a> text2 <a href="https://vk.com/">vk.com</a> text3
Answer 3

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

В C# для замены можно использовать статический метод Regex.Replace. Метод получает на вход строку, шаблон поиска, шаблон замены, и возвращает строку, в которое все совпадения заменены указанным образом.

Рассмотрим шаблон (a|b)(c|d). Он совпадает с подстроками ac, ad, bc, bd. Когда совпадение будет обнаружено библиотека регулярных выражений создаст подстановку для каждой пары скобок, то есть всего две. Первая подстановка $1 будет хранить первый совпавший символ, а вторая $2 — второй.

Regex.Replace("fadh", "(a|b)(c|d)", "g$2$1i");
// "fgdaih"

Как это работает? Библиотека находит подстроку ad внутри fadh. Поскольку в шаблоне поиска две пары скобок, библиотека запомнит две подстановки: в $1 попадёт символ a, а в $2 — символ d. Затем вся подстрока целиком будет заменена на шаблон g$2$1i, то есть на gdai. Всё, что было до найденного совпадения, и то, что будет после него, останется неизменными. Таким образом результатом замены будет строка fgdaih.

Для того, чтобы заменить URI на ссылку, надо использовать синтаксис:

public string ParsingLink(string text)
{
    return Regex.Replace(text, "(...)", "<a href=\"$1\">$1</a>");
}

Здесь вместо ... нужно указать регулярное выражение, соответствующее URI, например вот это:

public string ParsingLink(string text)
{
    return Regex.Replace(text,
                         @"((http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)",
                         "<a href=\"$1\">$1</a>");
}
Answer 4

По моему там в одну команду реализуется.

Regex.Replace(text, "((http|https|ftp|ftps)://[^\s]+)", "<a href=\"{1}\">{1}</a>");
READ ALSO
Как получить массив из json в c#

Как получить массив из json в c#

Есть страница php которая получает данные из базы и преобразует в jsonПолучаю через Web запрос строку с json и десериализую через библиотеку Newtonsoft

250
Не понимаю как работает Regex

Не понимаю как работает Regex

Хочу обернуть теги вида: #янаморе, #какделаВ кликаблельные ссылки

156
SQLGeography in SQL Server

SQLGeography in SQL Server

Строю полигоны в c# и заполняю ими соответствующую табличку в sqlserver(где уже есть информация и айдишники полигонов), примерно вот так:

196
Проблема с делегатами и событиями в Unity

Проблема с делегатами и событиями в Unity

Не могу разобраться как использовать делегаты и события в проекте UnityУ меня есть класс Observer

146