0

lpeg如果字符串不在某个开始和结束分隔符之间,我想了解如何替换字符串。下面是一个示例,我想在其中使用SKIPstartSKIPstop表示不应替换文本的位置。

rep
rep
SKIPstart
rep
rep
SKIPstop
rep
rep

new
new
SKIPstart
rep
rep
SKIPstop
new
new

这是另一个带有多个分隔符的示例:

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

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

并嵌套

rep
rep
SKIPstart
rep
SKIPstart
rep
SKIPstop
rep
SKIPstop
rep
rep

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

2 回答 2

1

抱歉,我不知道 lpeg,但你的任务很容易用通常的 Lua 模式解决。
在大多数情况下,IMO、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-18T02:28:47.763 回答
0

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-20T07:02:57.147 回答