2010-10-14 2 views
2

Я разборе BB код изображения тег:C# Regex.Replace(): получение значения

[IMG] http://imagesource.com [/ IMG]

I используя следующую функцию Replace():

Regex.Replace(msg, @"\[img\]([^\]]+)\[\/img\]", @"<img src=""$1"" border=""0"" />", RegexOptions.IgnoreCase); 

И мне нужно получить URL-адрес при разборе. Мне нужно знать значение «1 доллар». Является ли это возможным? Класс Regex каким-то образом заменяет строку «$ 1» значением, которое мне нужно, поэтому должен быть способ получить его.

+0

Разбор bbcode с регулярным выражением имеет те же недостатки, что и разбор HTML с регулярным выражением, так как ни один из них не является обычным языком. См. Http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454. Вы должны изучить использование парсера bbcode (быстрый поиск по поисковой сети http: //bbcode.codeplex.com/) –

ответ

6

Похоже, вы ищете метод Replace с перегрузкой, которая принимает MatchEvaluator. Страница MSDN для этого метода может быть найдена here.

Попробуйте вместо этого:

string input = "[img]http://imagesource.com[/img]"; 
string pattern = @"\[img]([^\]]+)\[\/img]"; 
string result = Regex.Replace(input, pattern, m => 
    { 
     var url = m.Groups[1].Value; 
     // do something with url here 
     // return the replace value 
     return @"<img src=""" + url + @""" border=""0"" />"; 
    }, 
    RegexOptions.IgnoreCase); 

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

string result = Regex.Replace(input, pattern, 
    m => @"<img src=""" + m.Groups[1].Value + @""" border=""0"" />", 
    RegexOptions.IgnoreCase); 

В вышеуказанном случае нет необходимости в return, но это просто возвращая исходную строку без дополнительной оценки. Вы могли бы придерживаться нескольких тернарных операторов и добавлять эту логику, но это будет выглядеть беспорядочно. Многопрофильная лямбда намного чище. Вы можете рассмотреть его по своему собственному методу, как показано в вышеупомянутой ссылке MSDN, если оно слишком велико или будет повторно использовано в других усилиях Regex.Replace.

BTW, я также упростил ваш рисунок, удалив экраны для ]. Необходимо только экранировать [.

+0

Удивительно! Это именно то, что мне нужно. Спасибо! – Alex

+1

Похоже, что первая группа содержит целую строку, поэтому он использовал m.Groups [1] – reggaeguitar

+0

@reggaeguitar, это правильно. Группа с индексом 0 содержит весь матч. –

0

Чтобы сохранить захваченную строку, просто «захватите» возвращаемое значение.

string s = Regex.Replace(msg, @"\[img\]([^\]]+)\[\/img\]", @"<img src=""$1"" border=""0"" />", RegexOptions.IgnoreCase); 
+0

Но это возвращает всю вещь ... – Alex

0

Захват группа доступна в собственности Захватывает на матч Regex, если вы спичку вместо того, чтобы заменить, то вы будете иметь доступ к группе.

+0

Я пробовал использовать «r.Match (текст). Группы [0]», но это не сработало – Alex

+0

Извините, я перечислил имущество. Свойство Captures имеет все группы захвата, группы - это группы названий Capture. Если нет именованных, то группы [0] - последний сопоставленный захват. –

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