lua lpeg 表达式在分隔符之间没有 gsub

Posted

技术标签:

【中文标题】lua lpeg 表达式在分隔符之间没有 gsub【英文标题】:lua lpeg expression to not sub in between delimeters 【发布时间】:2022-01-20 19:27:21 【问题描述】:

我想了解如果字符串不在某个开始和结束分隔符之间,我如何可以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

【问题讨论】:

【参考方案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

【讨论】:

我可能需要一段时间来消化这个......但它可以与多个分隔符一起使用吗?嵌套怎么样? \1%0 是什么意思?只是你用来掩盖分隔符的一点内部标志? would it work with multiple delimiter? - 请在问题中添加多个分隔符的示例。 Just a little internal flag you used to mask the delimiter? - 是的,这是无法在 Lua 模式中编写 (abc)? 的解决方法 我添加了更多示例。 would it work with multiple delimiter? How about nested? - 是的。是的。【参考方案2】:

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)

【讨论】:

当然,我以前不知道使用%z 的技巧已经让事情变得容易多了。我会花一些时间来消化这个并批准它作为答案。不过出于好奇,我已经看到在 LPEG 中使用了表格(指向子表达式的指针)。为什么使用 re.compile 而不是表?谢谢 我个人更喜欢使用 LPeg.re 而不是裸 LPeg,因为它比普通 LPeg 更容易理解和编写。

以上是关于lua lpeg 表达式在分隔符之间没有 gsub的主要内容,如果未能解决你的问题,请参考以下文章

awk 处理字符

lua——string之string.gsub

Lua string.gsub 带连字符

Lua模式匹配

Lua模式匹配

Lua 字符串替换