可针对多种模式进行有效字符串匹配的数据结构

时间:2018-06-20 13:51:25

标签: algorithm language-agnostic pattern-matching string-matching trie

我正在寻找一种有效的数据结构,该结构允许字符串与模式匹配。模式遵循类似于语法的正则表达式,但允许递归。它们包含可选,选择和递归/通配符。模式的一些示例是:

how many * (are coming|came) to (the)? party
(drunk|sober)? people
annoying *

这些模式将与以下字符串匹配:

how many drunk people are coming to the party
how many people came to party
how many annoying drunk people are coming to the party

对于那些失败,将会失败:

how many are coming to the party  <-- expected something else after 'many'
drunk sober people  <-- has to be either 'drunk' or 'sober' but not both

语法与正则表达式基本相同。除了*期望在该位置有另一个匹配的模式。 ()是一个简单的组。 ()?是一个可选组。 (choice1|choice2)是一个选择组。

有关模式/输入的更多信息

  • 大约有10,000个图案
  • 大多数模式都少于200个字符
  • 模式应支持unicode格式(尽管其中大多数可能仅包含ASCII字符)
  • 输入的内容为句子列表
  • 每个句子都应该匹配一个模式(它是嵌套模式)
  • 句子通常少于200个字符
  • 大多数句子包含少于5种不同的模式(例外 带有算术表达式的句子可能包含很多 更多模式)
  • 大多数句子是正确的,并且成功匹配了模式
  • 验证句子是否有意义尚不重要

要求

  • 数据结构应具有存储效率(10MB可能还可以, 不是100MB)
  • 数据结构应支持在运行时添加模式(删除并不重要,添加不必太快)
  • 数据结构的构建时间(秒)应该不会太长
  • 匹配应该相当快,目标是每秒10 000句以上

天真解决方案1 ​​ 将所有模式存储在数组中,并尝试一个接一个地匹配,直到我们成功或到达列表的末尾。递归会非常缓慢。所以不是一种选择。

天真的解决方案2 从所有可能的模式构建前缀/ patricia / ... trie,并包括一些用于通配符的特殊节点。这样比较好,但是每个可选/选择组都会创建其他模式。这使得树很快“爆炸”。尤其是因为它将创建许多分支,这些分支在根部附近不同但在叶部附近非常相似。

更复杂的解决方案 根据模式中的单词创建特里,并为其分配唯一索引。使用trie,我们可以将输入字符串转换为整数序列。但是然后我需要一些方法来将整数与模式进行匹配。不太确定该怎么做。

我觉得应该有一个解决这类问题的好方法。我猜想树表示是正确的选择,但是我找不到适合任务的任何算法/数据结构。有没有人为我解决过类似的问题和一些建议?

注意:这只是我的玩具项目。我不是在寻找某种生产质量工具,我也不是很在意我要花多长时间来实施它。只是好奇是否存在一个好的解决方案。

1 个答案:

答案 0 :(得分:0)

这似乎是context-free grammars的特例。不幸的是,由于可能存在歧义,因此您的定义并未将其进一步限制为deterministic context-free grammar。据我所知,最好的选择是Earley parserCYK algorithm