Выражение регулярных выражений .NET, чтобы найти вложенный текст

1

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

"this text needs to be displayed **bold**"

"**this** text **needs** to be displayed **bold**"

к этим:

"this text needs to be displayed <bold>bold</bold>"

"<bold>this</bold> text <bold>needs</bold> to be displayed <bold>bold</bold>"

Если я использую следующее:

string inputString = "this text needs to be displayed **bold**";
var reg = new Regex(@"\*\*([^\*]+)\*\*");
var outputString = reg.Replace(inputString, match => "<bold>" + match.Value + "</bold>");

строка вывода выглядит так:

"this text needs to be displayed <bold>**bold**</bold>"

Другими словами, match.Value включает звездочки.

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

(?<=\*\*).+?(?=\*\*)

Это дает правильное первое совпадение, но неверно для последующих совпадений; как используется в приведенном выше фрагменте кода, я получаю следующую последовательность совпадений (match.Value) для второй примерной строки:

this
 text 
needs
 to be displayed
bold

Кажется, он возвращает каждое появление строки, падающей между парами звездочек, а не "спаривания" их по мере необходимости.

Если я использую инструмент онлайн-регулярных выражений, например rubular, мое первоначальное решение кажется правильным (звездочки удалены с совпадений), но это не то, что возвращается реализацией.NET.

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

  • 0
    Я очень извиняюсь, но это никогда не будет работать надежно, см. Stackoverflow.com/questions/16358582/… для подсказки, почему. Если вы хотите, чтобы он был точным, забудьте регулярное выражение и напишите анализатор с сохранением состояния.
Теги:

2 ответа

1
Лучший ответ

Ссылка на группу захвата внутри вызова замены.

var outputString = reg.Replace(inputString, "<bold>$1</bold>");

Идеальная демонстрация

1

Иногда, для немного большего контроля, я предпочитаю использовать перегруженную версию Regex.Replace, которая использует делегат MatchEvaluator:

Regex.Replace(input,
              @"\*\*(?<a>.*?)\*\*",
              m => string.Format("<bold>{0}</bold>", m.Groups["a"].Value))

хотя для такой простой задачи:

Regex.Replace(input,
              @"\*\*(?<a>.*?)\*\*", 
              @"<bold>${a}</bold>")

было бы достаточно

  • 0
    Очень полезная, но менее известная перегрузка делегата

Ещё вопросы

Сообщество Overcoder
Наверх
Меню