正则表达式不匹配模式中最后一个字符的第一个实例

时间:2012-11-08 17:04:57

标签: c# regex parsing webserver

对于令人困惑的标题感到抱歉,但我不确定如何更好地解释它。

我正在为一个必须解析自定义脚本语言的学校项目构建一个简单的Web服务器。我有一行看起来像这样:

<p>Here's the date: <% pr date() %></p><p>Here's the date again: <% pr date() %></p>

我正在使用以下正则表达式来尝试拉出&lt;%...%&gt;东西...

<% *(.*) *%>

问题是它是从第一个开放标记到最后一个结束标记的匹配,而不是从第一个开放标记到第一个结束标记的匹配。所以得到的匹配是这样的:

<% pr date() %></p><p>Here's the date again: <% pr date() %>

...而不是:

<% pr date() %>

我认为我可以通过使用类似的东西来解决它,但它似乎不起作用:

<% *([^(<%)]*) *%>

......但它似乎不起作用。感谢任何帮助。谢谢。

2 个答案:

答案 0 :(得分:2)

  

问题是它是从第一个开放标签到最后一个结束标签的匹配

您需要一个非贪婪的匹配,在第一次识别匹配时停止:

.*  --> greedy ("maximum munch")
.*? --> non-greedy ("minimal munch")

非贪婪量词当然可以应用于大多数其他模式。

但是,我建议不要使用正则表达式。元模式OPEN-TOKEN CONTENT CLOSE-TOKEN对于手写解析器/扫描器来说非常简单。这样你就可以更容易地识别你的标签何时在评论中(并且可能还有其他情况你不想要匹配):

<!-- <% xyz %> -->

您可能不会鼓励上述代码,但您必须考虑这一点。


脚注:每当你(write a parser|fire a regular expression),你已经有一条腿在监狱里。

答案 1 :(得分:1)

您正在使用贪婪量词的.*

使用.*?代替.*,这是一个惰性量词

即使用正则表达式<%(.*?)%>


所以,<%(.*)%>会匹配,直到找到的最后 %>

<%(.*?)%>会匹配,直到找到的第一个 %>