【发布时间】:2019-01-08 12:55:12
【问题描述】:
我正在编写一个Elder Scrolls Online 插件,它由名为Havok Script 的经过轻微修改的Lua 5.1 引擎支持。此 Lua 环境不允许访问 os、io、package、debug 模块或任何本机平台绑定,并且无法绕过此限制,因为 ESO 是专有软件。
在这个受限的环境中,我需要一个功能齐全的正则表达式引擎,它具有环视功能(负向和正向的前瞻和后视)。性能几乎无关紧要,但方便性是最重要的问题(我没有时间或能力编写自己的正则表达式引擎)。
正则表达式引擎的实际语法不如功能集重要。所以 PCRE、JS 正则表达式、Java 正则表达式或 .NET 正则表达式引擎,以上任何一种,甚至有点不同的东西,都可能没问题。 POSIX 太简单了,因为它不支持任何环视行为。
正则表达式将是未经验证的用户输入,但环境实际上是一个沙盒,因此用户无法对它们进行任何恶意操作。由于输入是用户输入,我不能“只”使用 LPEG 之类的东西;用户群绝对会反对必须学习一个全新的概念,例如 LPEG,而不是相对熟悉的正则表达式语法。
在寻找 Lua 正则表达式引擎时,我已经用尽了许多选择:
- 与本机平台的绑定,如 lregexp 和其他 libpcre Lua 绑定。这些绝对不会也永远不会适用于我的用例,因为环境无法访问本机平台,所以它们被淘汰了。
- reLua,它支持基本的“常规”模式,如交替和贪婪闭包,但绝对没有环顾行为。我没有能力为这个项目添加环视,所以除非存在一个添加的分支,否则我不能使用它。
- 使用 castl 将在纯 JavaScript 中实现的完整正则表达式引擎(不使用 JS 的内置正则表达式函数)转换为 Lua。这有点有希望,但我在 castl 中遇到了fatal flaw,显然还有tessel,因为 Lua 的每个范围的变量限制为 200,而这些转译器没有任何解决方法(他们要做的就是将一个局部变量声明为一个表并将所有数据填充到该表中,然后将原始 JS 中的所有引用从局部变量访问更改为 Lua 中的表访问)。因为这是一个非常基本的问题,我不确定这是否可行,但也许最接近解决方案的方法是尝试通过以某种方式解决这个问题来解决这个问题?
- 我已经从 JS 以外的其他语言中寻找过编译器,但没有找到。基本上,我能找到的唯一“将 X 语言转换为纯 Lua”编译器是 castl 和 tessel。
- 我也(绝望地)尝试转译一个最新的emscriptened libpcre(对于初学者:编译成 JS 的 C 代码),然后使用 castl 将 that 转译成 Lua。这会导致在运行代码时出现更奇怪的 Lua 错误,Lua 解释器无法找到要求
goto的标签,尽管该标签明显存在于代码中。我只能认为这是因为生成的代码非常庞大,以至于 Lua 放弃了寻找它。
目前我陷入了僵局;我不知道如何继续获得我想要的功能。是否有一个库可以为 Lua 提供一个纯 Lua、功能齐全的正则表达式引擎,但我还没有找到?我放弃了谷歌的第七或第八页。
【问题讨论】:
-
the Lua interpreter can't find a label it's been asked to gotoLua 5.1 在其语法中没有goto和标签。这是 Lua 5.2 的功能。 -
LPEG 的
remodule 是否满足您的需求? -
LuLpeg(纯 Lua LPEG)的
re模块效果很好。上游 LPEG 不起作用,因为它是本机代码。感谢您的指点——我认为 LPEG 只是它自己的东西,我不知道它有一个相对易于访问的正则表达式引擎,它与 PCRE 足够相似,易于使用。谢谢 - 你能把它作为答案发布吗? -
@EgorSkriptunoff 谢谢——我认为
castl不适合我的需要,因为它生成 Lua 5.2 代码而不是 Lua 5.1 代码。我想用 if/then/else 重写大量的无条件 goto 将是不平凡的。 -
@ShaH 感谢您的评论,但之前的海报已经提供了该答案——请参阅 Henri Menke 的评论。他甚至更进一步,提到了一些我不知道的东西,这对我帮助很大:有一个 LPEG 模块,它接受非常熟悉的正则表达式语法,并将使用底层 LPEG 引擎来执行它。您的评论没有提到 LPEG 的
re模块,这是我最终使用的,因此它的用处稍差。不过,感谢您的帮助。