如何有效地匹配Lua中表中的键?

时间:2017-01-19 15:07:32

标签: lua pattern-matching pcre lpeg

在我的Lua 5.1环境中可用显然是默认的Lua模式匹配,但也是PCRE和LPEG的合理最新版本。我并不诚实地关心使用这些中的哪一种;只要我的问题以有效的方式得到解决,我就会感到高兴。 (我个人对LPEG的了解尤其是不存在的,但我听说它具有一些非常好的品质。)

我有一个表格,其中某些字符串模式作为键,一旦键匹配,就会使用附带的值...这意味着它们对此事件并不重要。

假设你有:

tbl = { ["aaa"] = 12, ["aab"] = 452, ["aba"] = -2 }

现在我的目标是找出这些匹配中的哪一个首先出现在"accaccaacaadacaabacdaaba"这样的特定字符串中。

实际上,密钥更多,匹配字符串相当长。这意味着简单地逐个匹配所有键并比较匹配开始的列是一个非常低效的解决方案,对我来说是不可行的。

匹配字符串的某些部分也可能存在相当大的重叠。从理论上讲,我知道每个关键模式的一个状态机在这方面是理想的;只需仔细检查每个模式的动作,并在完成其中一个完全匹配的那一刻就完成了。

但是当我的环境中存在如此多的模式匹配库时,我会疯狂地去编写类似的东西。我所知道的唯一一个技术上能力的是PCRE;只需附加"aaa|aab|aba"之类的密钥,即可获得第一个可行的匹配。

但也有问题。首先,我不确定编译这样的匹配时有多聪明。 (我认为它首先尝试' aaa',一旦失败完全展开,然后完全尝试,但我还没有经过测试)与匹配它相比,它不会太有效率{ {1}}可以更快地解决相似问题。

此外,我希望有能力提供一些灵活性(" a.ad"第二个角色不重要,或匹配数字......基本的东西像那样)。在这种加法方法中使用类似的模式,我没有看到重新获得匹配的原始模式的方法,因此我可以使用与之相关的值。

(最糟糕的情况是,我可以在表格中生成大量条目以匹配每个可能的通配符变体并取消模式要求,但老实说我不想。)

哪个库是正确的工具,并且可以启动,如何最好地使用所述库来实现上述目标而无需重新发明轮子?

1 个答案:

答案 0 :(得分:0)

对您的问题的评论提到Aho–Corasick算法。

如果您的环境可以访问os.executeio.popen,则可以调用fgrep -o -f patterns filename,其中patterns是包含用换行符分隔的模式的文件名,以及filename是您输入的名称。 -o表示仅输出匹配项,每行一个。您可以将filename替换为-,以便fgrep从标准输入echo "String to match" | fgrep -o -f patterns中读取。

fgrep实现了Aho–Corasick算法。

但是,请记住,Aho–Corasick算法不能识别元字符。