对于令人困惑的标题感到抱歉,但我不确定如何更好地解释它。
我正在为一个必须解析自定义脚本语言的学校项目构建一个简单的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() %>
我认为我可以通过使用类似的东西来解决它,但它似乎不起作用:
<% *([^(<%)]*) *%>
......但它似乎不起作用。感谢任何帮助。谢谢。
答案 0 :(得分:2)
问题是它是从第一个开放标签到最后一个结束标签的匹配
您需要一个非贪婪的匹配,在第一次识别匹配时停止:
.* --> greedy ("maximum munch")
.*? --> non-greedy ("minimal munch")
非贪婪量词当然可以应用于大多数其他模式。
但是,我建议不要使用正则表达式。元模式OPEN-TOKEN CONTENT CLOSE-TOKEN
对于手写解析器/扫描器来说非常简单。这样你就可以更容易地识别你的标签何时在评论中(并且可能还有其他情况你不想要匹配):
<!-- <% xyz %> -->
您可能不会鼓励上述代码,但您必须考虑这一点。
脚注:每当你(write a parser|fire a regular expression)
,你已经有一条腿在监狱里。
答案 1 :(得分:1)
您正在使用贪婪量词的.*
使用.*?
代替.*
,这是一个惰性量词
即使用正则表达式<%(.*?)%>
所以,<%(.*)%>
会匹配,直到找到的最后 %>
<%(.*?)%>
会匹配,直到找到的第一个 %>