0

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

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

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

我正在使用以下正则表达式来尝试提取 <% ... %> 东西...

<% *(.*) *%>

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

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

...代替:

<% pr date() %>

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

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

...但它似乎不起作用。任何帮助表示赞赏,谢谢。

4

2 回答 2

2

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

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

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

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

但是,我建议不要使用正则表达式。元模式OPEN-TOKEN CONTENT CLOSE-TOKEN对于手写解析器/扫描器来说足够简单。然后,您也可以更轻松地识别您的标签何时在评论中(可能还有其他情况是您不想要匹配):

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

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


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

于 2012-11-08T17:07:25.897 回答
1

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

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

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


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

<%(.*?)%>将匹配到它找到的第一个 %>

于 2012-11-08T17:08:10.743 回答