lpeg中的非贪婪搜索,而不消耗最终匹配

  • 本文关键字:贪婪 搜索 lpeg lua peg lpeg
  • 更新时间 :
  • 英文 :


这是从对这个问题的评论中派生出来的。

正如我所理解的,在PEG语法中,可以通过编写S <- E2 / E1 S(或者s=模式E2,如果可能的话,或者模式E1和连续的s(来实现非贪婪搜索。

然而,我不想在最终模式中捕获E2——我想捕获E2。当我试图在LPEG中实现这一点时,我遇到了几个问题,包括在将其构建到语法中时出现的"规则中的空循环"错误。

我们将如何在LPEG语法中实现以下搜索:[tag] foo [/tag],其中我们希望在捕获表中捕获标记的内容(示例中为"o"(,但我们希望在结束标记之前终止?正如我从对另一个问题的评论中所理解的,这应该是可能的,但我在LPEG中找不到一个例子。

以下是测试语法的一个片段

local tag_start = P"[tag]"
local tag_end = P"[/tag]"
G = P{'Pandoc', 
...
NotTag = #tag_end + P"1" * V"NotTag"^0;
...
tag = tag_start * Ct(V"NotTag"^0) * tag_end;
}

又是我。我认为您需要更好地了解LPeg捕获。表捕获(lpeg.Ct(是一种在表中收集捕获的捕获。由于在NotTag规则中没有指定简单捕获(lpeg.C(,因此最终捕获将变成一个空表{}

再次,我建议您从lpeg.re开始,因为它更直观。

local re = require('lpeg.re')
local inspect = require('inspect')
local g = re.compile[=[--lpeg
tag       <- tag_start {| {NotTag} |} tag_end
NotTag    <- &tag_end / . NotTag

tag_start <- '[tag]'
tag_end   <- '[/tag]'
]=]
print(inspect(g:match('[tag] foo [/tag]')))
-- output: { " foo " }

此外,S <- E2 / E1 S不是S <- E2 / E1 S*,这两者是不等价的。


然而,如果我要做同样的任务,我不会尝试使用非贪婪匹配,因为非贪婪匹配总是比贪婪匹配慢。

tag <- tag_start {| {( !tag_end . (!'[' .)* )*} |} tag_end

结合非谓词和贪婪匹配就足够了。

相关内容

  • 没有找到相关文章

最新更新