【问题标题】:Data structure for efficient string matching against many patterns针对多种模式进行高效字符串匹配的数据结构
【发布时间】:2018-11-29 16:28:18
【问题描述】:

我正在寻找一种允许字符串到模式匹配的高效数据结构。这些模式遵循类似正则表达式的语法,但允许递归。它们包含可选项、选项和递归/通配符。一些模式示例如下:

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,并为它们分配一个唯一索引。使用 trie,我们可以将输入字符串转换为整数序列。但是我需要一些方法来将整数与模式匹配。不太确定该怎么做。

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

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

【问题讨论】:

  • 你检查过en.wikipedia.org/wiki/… 吗?
  • 考虑构建一个有限状态机:en.wikipedia.org/wiki/Finite-state_machine.
  • @juvian 是的,我做到了,但这些算法用于精确的字符串匹配。
  • @JimMischel 状态机是一个选项,但我正在寻找更具体的东西。
  • 我看到提到的递归,但没有看到任何例子。

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


【解决方案1】:

这看起来像是context-free grammars 的一个特例。不幸的是,您的定义并未将其进一步限制为deterministic context-free grammar,因为可能存在歧义。所以据我所知,你最好的选择是Earley parserCYK algorithm

【讨论】:

  • 非常感谢您的链接!我一定会看看他们。
  • 我查看了来源,我有两个担忧。首先,语法大小会很大,而且算法似乎只是尝试一个接一个地匹配一个模式(这是我想要避免的)。其次,看起来您不能在运行时向语法添加额外的规则。但我很确定我可以以某种方式实现它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多