Я записал регулярное выражение, которое автоматически обнаруживает URL в произвольном тексте, который вводят пользователи. Это не такая простая задача, поскольку это может казаться сначала. Jeff Atwood пишет об этом в его сообщении.
Его работы регулярного выражения, но потребности дополнительный код после того, как обнаружение сделано.
Мне удалось записать регулярное выражение, которое делает все в единственном движении. Это - то, как это похоже (я разломал его, на разделяют строки для создания этого более понятным, что это делает):
1 (?\()?
2 (?http(?s)?://)?
3 (?
4 (?(scheme)
5 (?:www\.)?
6 |
7 www\.
8 )
9 [a-z0-9]
10 (?(outer)
11 [-a-z0-9/+&@#/%?=~_()|!:,.;čšžćđ]+(?=\))
12 |
13 [-a-z0-9/+&@#/%?=~_()|!:,.;čšžćđ]+
14 )
15 )
16 (?(?(outer)\)))
Как можно видеть, я использую названные группы получения (используемый позже в Regex.Replace()
) и я также включал некоторые локальные символы (čšžćđ), которые позволяют нашим локализованным URL быть проанализированными также. Можно легко опустить их, если Вы хотели бы.
Так или иначе. Вот то, что это делает (относящийся к номерам строки):
if
оператор, который говорит: если "sheme" присутствовал затем www., часть является дополнительной, в других отношениях обязательной, чтобы строка была ссылкой (таким образом, это регулярное выражение обнаруживает все строки, которые запускаются или с http или с www),http://
или www.
должна быть или буква или число (это может быть расширено, если требуется покрыть еще больше ссылок, но я решил не к тому, потому что я не могу думать о ссылке, которая запустилась бы с некоторого неясного символа),if
оператор, который говорит: если "внешний" (фигурные скобки) присутствовал, получают, все до последних закрывающих фигурных скобок иначе получает всеПервая и последняя строка раньше имела \s*
в них также, таким образом, пользователь мог также записать открытые фигурные скобки и вставить пространство прежде, чем вставить ссылку.
Так или иначе. Мой код, который действительно связывает замену с фактическими элементами HTML привязки, точно походит на это:
value = Regex.Replace(
value,
@"(?\()?(?http(?s)?://)?(?(?(scheme)(?:www\.)?|www\.)[a-z0-9](?(outer)[-a-z0-9/+&@#/%?=~_()|!:,.;čšžćđ]+(?=\))|[-a-z0-9/+&@#/%?=~_()|!:,.;čšžćđ]+))(?(?(outer)\)))",
"${outer}http${secure}://${url}${ending}",
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
Поскольку Вы видите, что я использую названные группы получения для замены ссылки с Тегом привязки:
"${outer}http${secure}://${url}${ending}"
Я мог также опустить http (s) часть в дисплее привязки, чтобы заставить ссылки выглядеть более дружественными, но на данный момент я решил не к.
Я хотел бы, чтобы мои ссылки были заменены сокращениями также. Таким образом, когда пользователь копирует очень длинную ссылку (например, если они скопировали бы ссылку с карт Google, которая обычно генерирует длинные ссылки), я хотел бы сократить видимую часть тега привязки. Ссылка работала бы, но видимая часть тега привязки будет сокращена к некоторому количеству символов. Я мог также добавить замещающий знак в конце вообще возможного (и сделать вещи еще более прекрасными).
Делает Regex.Replace()
заменяющие нотации поддержки метода так, чтобы я мог все еще использовать единственный вызов? Что-то подобное как string.Format()
метод делает, когда требуется отформатировать значения в формате строки (десятичные числа, даты и т.д....).
Вы можете разделить $ {url}
на две группы захвата - urlhead
, с количеством символов, которое вы хотите отобразить, и urltail
с остальными. Вот пример с 10 символами; это несколько упрощено, чтобы удалить условие, последний (?
должен позаботиться об этом - он возвращает и захватывает последний )
при необходимости:
(?<outer>(?<=\())?
(?<scheme>http(?<secure>s)?://)?
(?<url>
(?(scheme)
(?:www\.)?
|
www\.
)
[a-z0-9]
[-a-z0-9/+&@#/%?=~_()|!:,.;čšžćđ]{1,10}
)
(?<urltail>[-a-z0-9/+&@#/%?=~_()|!:,.;čšžćđ]+)
(?<ending>(?(outer)(?=\))))
Обратите внимание, что я также изменил внешний
и окончание
на поисковые пути, чтобы они не захватывались и не заменялись. Строка замены в этом случае выглядит так:
<a href=\"http${secure}://${url}${urltail}\">http${secure}://${url}</a>
Вам нужно будет использовать перегрузку Regex.Replace, которая использует MatchEvaluator
, делегат, который создает замещающий текст для вас.
См. Здесь: http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.matchevaluator.aspx
Технически это возможно только с помощью регулярных выражений, делая то, что Коби предлагает. Однако я не уверен, что хотел бы попросить кого-нибудь (включая себя через несколько месяцев) поддерживать это регулярное выражение.