Я бил головой о стену в этот день весь день и приближаюсь к моему концу. Ищете новую перспективу.
Пример ввода текста:
(разрывы строк добавлены для ясности, а не фактические данные)
</div>#My Novel<br />
##Chapter1<br />
It was a dark and stormy night<br />
##Chapter 2<br />
The End
Желаемый результат
</div><h1>My Novel</h1><br />
<h1>Chapter1</h1><br />
It was a dark and stormy night<br />
<h1>Chapter 2</h1><br />
The End
Фактический выход
</div><h1>My Novel</h1><br />
##Chapter1<br />
It was a dark and stormy night<br />
<h1>Chapter 2</h1><br />
The End
Вот выражение соответствия
(отформатированные для легкого чтения, комментарии /linebreaks не находятся в выражении)
(?<preamble>
(
([<]\/\w+\d*[>])|([<]\w+\d*\s*\/[>]) #</tag> or <tag />
)
\s* #optional whitespace
)
(?<hashmarks>
\#{1,6} #1-6 hash marks
)
(?<content>
.+? #header content
)
(?<closing>
([<](br|\/\s*br|br\s*\/)[>]) #<br>,</br>, or <br />
)
Вот выражение Expression
${preamble}<h1>${content}</h1>${closing}
Если это важно, я использую следующую перезагрузку С# regex.replace:
Regex.Replace(Source,SrchExp,ReplExpr,RegexOptions.IgnoreCase)
Вопрос (наконец)
Кто-нибудь может понять, почему он заменяет #My Novel и ## Chapter 2, но не ## Chapter 1?
Извините за длинный пост, и, надеюсь, я не делал ничего, пытаясь отформатировать его, чтобы сделать его доступным для SO.
Обновление:
Еще одна вещь, которая может помочь. Добавление дополнительного тега разрыва сразу после "Романа" заставляет готовый код работать отлично. Пока не знаю, почему.
Пример ввода текста (изменен):
</div>#My Novel<br /><br />
##Chapter1<br />
It was a dark and stormy night<br />
##Chapter 2<br />
The End
Вот тот, который был фактически протестирован и, похоже, работает.
Проблема в том, что как только совпадение найдено, поиск продолжается точно там, где первый остановился. В результате закрытие <br />
of #My Novel
больше не будет снято, и поэтому #Chapter1
будет пропущен.
Чтобы в любом случае записать конструкторы типа #Chapter1
, мы можем использовать утверждение lookbehind. Lookbehinds обеспечивает наличие префикса, даже если оно продолжается до текущей позиции. Это также предотвращает необходимость отбросить его в строке замены:
Замените (?<preamble>
на (?<=
Затем в заменяющей строке удалите часть ${preamble}
.
Общее выражение поиска теперь выглядит следующим образом:
(?<= # removed the preamble capture and replaced with a lookbehind
(
([<]\/\w+\d*[>])|([<]\w+\d*\s*\/[>]) #</tag> or <tag />
)
\s* #optional whitespace
)
(?<hashmarks>
\#{1,6} #1-6 hash marks
)
(?<content>
.+? #header content
)
(?<closing>
([<](br|\/\s*br|br\s*\/)[>]) #<br>,</br>, or <br />
)
И строка замены выглядит так:
<h1>${content}</h1>${closing}
Наш результат теперь верно:
</div><h1>My Novel</h1><br />
<h1>Chapter1</h1><br />
It was a dark and stormy night<br />
<h1>Chapter 2</h1><br />
The End
(?<closing>
прогнозом на будущее : (?=