整天都把我的头靠在墙上,我正在靠近我的智慧结束。寻找一些新的视角。
示例输入文字:
(为了清晰起见,添加了换行符,而不是实际数据)
</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
这是匹配表达式
(格式化以便于阅读,评论/换行符不在表达中)
(?<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 />
)
这是替换表达式
${preamble}<h1>${content}</h1>${closing}
如果重要,我使用以下C#regex.replace重载:
Regex.Replace(Source,SrchExp,ReplExpr,RegexOptions.IgnoreCase)
问题(最后)
任何人都可以看到它为什么取代#My Novel和##第2章,而不是##第1章?
对于这篇长篇文章感到抱歉,希望我没有尝试将其格式化以使其可读为SO。
更新:
还有一件事可能有所帮助。在“Novel”之后添加额外的break标记使得提供的代码开始完美运行。不知道为什么。
示例输入文字(已修改):
</div>#My Novel<br /><br />
##Chapter1<br />
It was a dark and stormy night<br />
##Chapter 2<br />
The End
答案 0 :(得分:2)
这是一个经过实际测试并且似乎有效的方法。
问题在于,一旦找到匹配项,搜索就会继续完全停止第一个搜索。因此,<br />
的结束#My Novel
将不会再次被捕获,因此会错过#Chapter1
。
无论如何要捕获#Chapter1
- 类似的构造,我们可以使用lookbehind assertion。 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