首页 > 解决方案 > 在 Lua 中存储 Lua 脚本

问题描述

我有一个用 C++ 编写的应用程序,可以显示、编辑和运行 Lua 脚本。此应用程序存储所有内容,包括项目文件中的完整 Lua 脚本。

这里的问题是项目文件的格式也是一个 Lua 文件,由 C++ 编写(它不是编写项目文件的 Lua 引擎)。

编辑器中的示例 Lua 脚本:

-- Message
local message =
[["First" line
Second line
Last line]]

现在,我想将上面的脚本保存在一个 lua 文件中。示例项目文件:

-- Project file
projectName = "test"
options = {}
options.autoRun = false

-- Lua source
luaScript =
[=[
-- Message
local message =
[["First" line
Second line
Last line]]
]=]

我当然可以将 Lua 脚本包含在 [=[ ... ]=] 中(如示例中所示),但如果脚本也包含相同的序列,它将无法工作。由于脚本是用户编写的任意脚本,我不能只是假设没有使用某个序列。

有没有办法在 XML 中包含诸如 CData 之类的“原始”数据?我会尽量避免对脚本进行编码,因为我希望它在项目文件中是可读的。

最简单的方法是 [ 和 ] 字符可以转义,但显然不能。

我可以将脚本分解为单个字符串,对其进行转义并将它们连接起来:

-- Project file
projectName = "test"
options = {}
options.autoRun = false

-- Lua source
luaScript = "-- Message\n"..
            "local message =\n"..
            "[[\"First\" line\n"..
            "Second line\n"..
            "Last line]]\n"..

但是这个解决方案并不容易直接在项目文件中阅读和编辑。

如果这是不可能的,那么最好得到确认,我很可能会使用编码方案而不是 B 计划。

解决方案
在探索了一些选项和indeas之后,我根据lhf的建议选择了解决方案。我已经为 Lua 编写器类编写了一些 C++,所以当我编写一个字符串时,我会检查它是否是一个多行字符串。如果是我只是[====================================================================[ -- MULLTILINE BEGIN\r\n在前面插入并附加字符串\r\n]====================================================================] -- MULLTILINE END,则无需转义字符串。如果它是单行字符串,我不添加任何内容,只对其进行转义。

添加 CR/LF 对和注释的原因是为了方便用户直接在项目文件中编辑脚本。

script =
[====================================================================[ -- MULLTILINE BEGIN
-- Lua script engine 5.3.4
function onData(data,ch)
  print("A 'String' within a \"string\" within a [===[string]===]")
end

-- Multiline within Multiline
a = [=[
Spicy jalapeno bacon ipsum dolor amet ground round eu chicken,
venison turkey corned beef dolore exercitation pastrami nostrud
prosciutto in drumstick deserunt meatloaf. Pastrami jowl beef
ribs minim eu pariatur est et lorem kielbasa shoulder. Dolore
officia cupidatat, biltong tempor ut ham kielbasa magna bacon
salami. Turducken tri-tip tail reprehenderit tenderloin aliquip.
]=]

print(a)
]====================================================================] -- MULLTILINE END

读回字符串时,我只是-- MULTILINE BEGIN\r\n在第一行查找。如果它在那里,我只需删除包含 CR/LF 对和最后一个 CR/LF 对的行。由于-- MULLTILINE END它是多行之外的注释,因此它不会是字符串的一部分,也不需要删除,只有在结束序列之前添加的 CR/LF 对。

标签: c++luaescapingraw-data

解决方案


您可以=根据需要在长字符串引号中使用任意数量[====[。只需在字符串中找到最长的=并添加一个=

您也可以%q在 string.format 中使用,它将引用所有需要引用的字符。


推荐阅读