lua lpeg 表达式中不在定界符之间替换

我想了解如何使用 lpeg 在不在某个起始和结束定界符之间时替换字符串。以下是一个示例,在此示例中,我想使用 SKIPstartSKIPstop 来表示不应该被替换的文本的位置。

rep
rep
SKIPstart
rep
rep
SKIPstop
rep
rep

to

new
new
SKIPstart
rep
rep
SKIPstop
new
new

这里还有一个带有多个定界符的示例:

rep
rep
SKIPstart
rep
rep
SKIPstop
rep
rep
SKIPstart
rep
rep
SKIPstop

to

new
new
SKIPstart
rep
rep
SKIPstop
new
new
SKIPstart
rep
rep
SKIPstop

和嵌套

rep
rep
SKIPstart
rep
SKIPstart
rep
SKIPstop
rep
SKIPstop
rep
rep

to

new
new
SKIPstart
rep
SKIPstart
rep
SKIPstop
rep
SKIPstop
new
new

原文链接 https://stackoverflow.com/questions/70400477

点赞
stackoverflow用户1847592
stackoverflow用户1847592

抱歉,我不了解lpeg,但是你的任务可以通过常规的Lua模式轻松解决。

在大多数情况下,我认为lpeg或其他外部正则表达式库都过于复杂,Lua模式足够好用。

local s = [[
rep
rep
SKIPstart
rep
rep
SKIPstop
rep
rep
SKIPstart
rep
SKIPstart
rep
SKIPstop
rep
SKIPstop
rep
rep
]]
s = s:gsub("SKIPstart", "\1%0")
     :gsub("SKIPstop", "%0\2")
     :gsub("%b\1\2", "\0%0\0")
     :gsub("(%Z*)%z?(%Z*)%z?",
         function(a, b) return a:gsub("rep", "new")..b:gsub("[\1\2]", "") end)
print(s)

输出:

new
new
SKIPstart
rep
rep
SKIPstop
new
new
SKIPstart
rep
SKIPstart
rep
SKIPstop
rep
SKIPstop
new
new
2021-12-18 02:28:47
stackoverflow用户17237579
stackoverflow用户17237579

Egor Skriptunoff的回答是使用标准Lua模式进行戏法的绝佳方法。我同意,如果有直接的方法可以解决问题,我不会推荐使用LPeg或其他外部库。

既然您问过了关于LPeg的问题,我将向您展示如何使用LPeg完成此操作。

local re = require('lpeg.re')

local defs = {
  do_rep = function(p)
    return p:gsub('rep', 'new')
  end
}

local pat = re.compile([=[--lpeg
  all <- {~ ( (!delimited . [^S]*)+ -> do_rep / delimited )* ~}
  delimited <- s (!s !e . / delimited)* e
  s <- 'SKIPstart'
  e <- 'SKIPstop'
]=], defs)

local s = [[
rep
rep
SKIPstart
rep
rep
SKIPstop
rep
rep
SKIPstart
rep
SKIPstart
rep
SKIPstop
rep
SKIPstop
rep
rep
]]

s = pat:match(s)
print(s)
2021-12-20 07:02:57