在 Lua 中获取一组带有字符串模式的括号内部和外部的字符串字符?

Getting string characters inside, and outside a set of brackets with string patterns in Lua?

我正在尝试创建一个字符串模式,它将匹配非 space 字符和一组括号内的所有字符。例如,这样的序列:

local str = [[
    This [pattern] should [return both] non-space 
    characters and [everything inside] brackets
]]

会打印出 This[pattern]should[return both]non-space ... 等。我一直在做这个一段时间,想出了一个非常 close 的解决方案,我知道这个问题,但似乎无法解决。这是我的尝试:

local str = [[
    This [pattern] should [return both] non-space 
    characters and [everything inside] brackets
]]

for s in string.gmatch(str, "%S+%[?.-%]?") do
    print(s)
end

问题是 spaces 应该允许在括号内,但不能在括号外。这将打印出如下内容:This[pattern]should[returnboth]non-space ...等

请注意,[returnboth] 是两个不同的捕获,与返回 [return both] 相对。我对字符串模式还是有点陌生​​,所以我觉得我可能会忽略一些选项。无论如何,如果有人对这类事情有经验,我肯定会很感激一些见解。

只是为了在评论中稍微解释一下 Egor 的解决方案,关键思想是区分括号 [] 内的空格和括号外的空格。这是通过

实现的
  • 首先 gsub 将括号外的空格替换为 [=14=]
  • 后跟 gmatch 匹配 non-null 个字符的字符串。

空字符 [=14=] 用作标记,因为它不太可能与输入文本中的合法字符冲突。

此方法的一个变体是替换括号内 的空格,而不是后跟匹配 non-whitespace 个字符

for s in str:gsub("(%[.-%])",
                  function(x)
                    return x:gsub("%s+", "[=10=]") 
                  end)
            :gmatch "%S+"
do
  print( (s:gsub("%z+", " ")) )
end

请注意,您是在解析过程中创建中间字符串。如果输入字符串很长,那么临时中间字符串也很长。对于 one-off 匹配,这可能没问题。如果您要处理更多 heavy-duty 解析,我建议您查看 LPEG.

例如,下面的lpeg.re语法可以解析给定的输入文本

local re = require 're'

local str =
[[
    This [pattern] should [return both] non-space 
    characters and [everything inside brackets]
]]

local pat = re.compile
  [[
    match_all   <- %s* match_piece+ !.
    match_piece <- {word / bracket_word} %s*
    word        <- ([^]%s[])+
    bracket_word <- '[' (word %s*)+ ']'
  ]]

for _, each in ipairs{ pat:match(str) } do
  print(each)
  end

输出:

This
[pattern]
should
[return both]
non-space
characters
and
[everything inside brackets]