需要有关正则表达式的帮助,而不是替换表达式的所有实例

时间:2009-08-07 23:26:36

标签: c# regex

整天都把我的头靠在墙上,我正在靠近我的智慧结束。寻找一些新的视角。

示例输入文字:
 (为了清晰起见,添加了换行符,而不是实际数据)

</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

1 个答案:

答案 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