0

这是从关于这个问题的评论中分离出来的。

据我了解,在 PEG 语法中,可以通过编写来实现非贪婪搜索S <- E2 / E1 S(或 S = 模式 E2,如果可能,或模式 E1 和继续 S)。

但是,我不想在最终模式中捕获 E2 - 我想最多捕获E2。当尝试在 LPEG 中实现这一点时,我遇到了几个问题,包括将其构建到语法中时出现“规则中的空循环”错误。

我们将如何在 LPEG 语法中实现以下搜索:[tag] foo [/tag]我们想在捕获表中捕获标记的内容(示例中为“foo”),但我们想在结束标记之前终止?正如我从对另一个问题的评论中了解到的那样,这应该是可能的,但我在 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;
}
4

1 回答 1

1

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

再一次,我建议你从头开始,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 Sis not S <- E2 / E1 S*,这两者不等价。


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

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

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

于 2022-01-19T07:45:23.513 回答