2013-12-10 3 views
3

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

var r = new Regex("(https?://[^ ]+)"); 
return r.Replace(Action, "<a target=\"_blank\" href=\"$1\">$1</a>"); 

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

например. http://myurl.com/my/route/th ...

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

+1

не возможно, по крайней мере, не с эллипсов. Кроме того, вы должны использовать [лучшее выражение для обнаружения ссылок] (http://daringfireball.net/2009/11/liberal_regex_for_matching_urls). (Один из подходов к решению этого вопроса - использование CSS ('a {display: inline-block; width: 20em; overflow: hidden; text-overflow: ellipsis;}') – Tomalak

+0

Итак, ограничения символов предназначены только для показа? (И фактические URL-адреса будут сохранены в полном объеме). Для этого вам не нужно регулярное выражение, просто подстройте полную ссылку и добавьте несколько точек ... – musefan

+0

@musefan Как вы используете подстроку для соответствия * любому URL-адресу? – Rawling

ответ

1

следующее регулярное выражение даст вам то, что вы после

((https?://[^ ]){20}[^ ]+) 

Что это делает, создавая 2 захвата группы

  1. Захват всего URL
  2. Захват URL до конкретного длина (в этом примере 20)

Все, что требуется, это добавить правду например,

Regex.Replace(Action, "((https?://[^ ]){20}[^ ]+)", "<a target=\"_blank\" href=\"$1\">$2...</a>")); 

См. Его в action.


Как указано в комментариях, выше, приведет к ..., добавленными всех URL-адресов (даже те, которые не превышают длину). Учитывая изменчивость этого, используя , только regex здесь, вероятно, нежизнеспособен. Однако мы можем разрешить это с небольшой настройкой регулярного выражения и некоторыми простыми манипуляциями с строками, например.

var match = Regex.Match(Action, "(https?://[^ ]{50})?[^ ]+"); 
// if the display part group has matched something, we need to truncate 
var displayText = match.Groups[1].Length > 0 ? String.Format("{0}...", match.Groups[1]) : match.ToString(); 
Console.WriteLine(String.Format("<a target=\"_blank\" href=\"{0}\">{1}</a>", match, displayText)); 

Я обновил example

+0

Вы получаете «...», даже если ссылка короткая. – Rawling

+0

@ Rawling ah yeah, так что бы вы хотели. Обновите, чтобы разместить это. – James

+0

Выглядит неплохо. Спасибо. – Nick

0

Я не думаю, что это можно сделать это с помощью простой замены регулярных выражений, но, к счастью, .NET позволяет выполнять гораздо более сложной замены. Во-первых, мы создали регулярное выражение, чтобы захватить первый (например) 25 знаков после начала URL в одной группе, а также любые дополнительные символы в секунду, необязательная группа:

var r = new Regex("(https?://[^ ]{1,25})([^ ]+)?"); 

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

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

var s = r.Replace(
    Action, 
    m => string.Concat(
     "<a target=\"_blank\" href=\"", 
     m.Value, 
     "\">", 
     m.Groups[1].Value, 
     (m.Groups[2].Success ? "..." : ""), 
     "</a>")); 

Для входа

"hello http://www.google.com world 
http://www.loooooooooooooooooooooooooooooooooooooooooong.com !" 

я получаю выходной

hello <a target="_blank" href="http://www.google.com">http://www.google.com</a> 
world <a target="_blank" 
    href="http://www.loooooooooooooooooooooooooooooooooooooooooong.com"> 
    http://www.loooooooooooooooooooo...</a> ! 
+0

Хотя это говорит о том, что если вы собираетесь спуститься по маршруту MatchEvaluator, вы можете полностью удалить группы и просто подстроить совпадение. Неутешительно, что регулярное выражение поддерживает условные " сделал эту группу matc h ", но только при согласовании, а не при замене. – Rawling

1

Это лучше всего решить изготовителем match evaluator, используя функцию, чтобы сделать t он заменяет.

string Action = "Somebody turn http://stackoverflow.com/questions/20494457/limiting-the-number-of-characters-using-regular-expression into a link please."; 
var r = new Regex("(https?://\\S+)"); 
return r.Replace(Action, 
    match => { 
     string display = match.Value; 
     if (display.Length > 30) 
     { 
      display = display.Substring(0, 30) + "..."; 
     } 
     return "<a target=\"_blank\" href=\"" + match.Value + "\">" + display + "</a>"; 
    }); 

Возвращает:

Somebody turn <a target="_blank" href="http://stackoverflow.com/questions/20494457/limiting-the-number-of-characters-using-regular-expression">http://stackoverflow.com/quest...</a> into a link please. 
+0

На мой вкус это лучший ответ –

Смежные вопросы