【问题标题】:How to Ignore Nested Brackets in a String in Lua?如何忽略Lua中字符串中的嵌套括号?
【发布时间】:2019-12-18 08:50:36
【问题描述】:

我有一组可以被认为是括号的特殊字符。当用户在这些括号之间包含一些文本时,我只是希望程序用<, > 替换使用的任何括号。因此,如果*, * 是方括号并且字符串是"Hello *world*",则程序应该返回"Hello <world>"

问题是我想避免这些括号对的嵌套出现,并且我只希望程序关注最外面的一对。换句话说,一旦创建了一个左括号,就处理所有将字符作为普通字符,直到左括号关闭。

例如,如果我的括号是*, *#, #,我的字符串是"Hello *wo#rl#d*",程序应该返回:"Hello <wo#rl#d>" 而不是:"Hello <wo<rl>d>"

我尝试使用string.gsub 来查找定义的特殊字符之间的所有文本模式,但当然,它不会忽略它们的嵌套出现。

local specialChars = {"*", "#", "-"}
local text = "Hello, world. *Won#der#ful* day, -don't- you #th*in*k?#"

for i = 1, #specialChars do
    local bracket = specialChars[i]
    local escBracket = "%" .. bracket

    text = string.gsub(text, escBracket .. "(.-)" .. escBracket, function(content)
        return "<" .. content .. ">"
    end)
end

print(text)

上面的代码应该显示:

"Hello, world. <Won#der#ful> day, <don't> you <th*in*k?>"

而是显示:

"Hello, world. <Won<der>ful> day, <don't> you <th<in>k?>"

任何帮助将不胜感激。

【问题讨论】:

  • text = text:gsub("([%*%#%-])(.-)%1", "&lt;%2&gt;")
  • @EgorSkriptunoff 非常感谢!这正是我想要的。如果我希望我的括号不止一个字符,这也可以吗?即**, **?
  • 没有。但是您可以在转换之前将所有多字符组合替换为 1 个字符的项目(未使用字符的示例:\001\002 等),并在转换后将它们替换回来。
  • @EgorSkriptunoff 哇,你真是个天才。非常感谢您的帮助和后续支持。
  • @EgorSkriptunoff 我想我还有一个问题,如果不是要求太多的话。现在我面临一个问题,我不能假设右括号与左括号的字符相同。例如,[[, ]]&amp;_, _&amp; 是括号对的情况。为此,我觉得我唯一的选择可能是遍历所有字符并以这种方式解析字符串...

标签: string design-patterns lua


【解决方案1】:
local text = "[[**Hello**, &_world_&.]] &_*Won#der#ful* day_&, **-don't- you** #th*in*k?#"
print(text)

local single_char = "*#-"
-- "o."=open, ".c"=close, "oc"=both open and close
local multi_char = { -- use chars "\1","\2",...,"\6" to start each group
   ["\1o."] = "[[", 
   ["\1.c"] = "]]",  
   ["\2o."] = "&_", 
   ["\2.c"] = "_&",
   ["\3oc"] = "**",
}
for k, v in pairs(multi_char) do
   text = text:gsub(v:gsub("%p", "%%%0"), k)
end
text = text
   :gsub("["..single_char:gsub("%p", "%%%0").."]", "%0oc")
   :gsub("([\1-\6"..single_char:gsub("%p", "%%%0").."])o.(.-)%1.c", "<%2>")
   :gsub("(["..single_char:gsub("%p", "%%%0").."])..", "%1")
   :gsub("[\1-\6]..", multi_char)
print(text)

输出:

[[**Hello**, &_world_&.]] &_*Won#der#ful* day_&, **-don't- you** #th*in*k?#
<**Hello**, &_world_&.> <*Won#der#ful* day>, <-don't- you> <th*in*k?>

【讨论】:

  • 这很棒。再次,我非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 2013-01-19
相关资源
最近更新 更多