【问题标题】:Find regex match in large dictionary using python quickly使用python快速查找大字典中的正则表达式匹配
【发布时间】:2021-11-01 23:03:56
【问题描述】:

我有一个包含正则表达式值作为键和一个数值作为值的大型字典,并给出了一个语料库(分解为单个单词标记的列表)我想找到最符合我的正则表达式值word 来获取其各自的值。

字典包含许多模棱两可的正则表达式值,从某种意义上说,一个单词可能有多个正则表达式匹配,因此您可能希望找到最长的正则表达式或“最佳匹配”(例如:字典包含 effect+,以及影响了感情)

我的问题是,当通过字典运行大型文本样本并查找每个单词标记的正则表达式匹配时,需要很长时间(每个单词 0.1 秒),这显然会增加 1000 多个单词。这是因为它每次都会遍历整个字典以找到“最佳匹配”。

有没有更快的方法来实现这一点?请在下面查看我的代码有问题的部分。

for word in textTokens:
    for reg,value in dictionary.items():
        if(re.match(reg, word)):
            matchedWords.append(reg)

【问题讨论】:

  • 这些正则表达式有一个特殊的结构,还是所有有效的正则表达式都可能?
  • 在整个字典中只使用了一种正则表达式,它是一个单词后的“+”量词(fault+、go+等)。
  • Sooooo 你说的是python的re 模块根本不适合这个任务,因为那些基本上不是正则表达式。
  • 当我读到你的问题时,首先想到的是prefix tree,你可以使用它来查找与单词匹配的最长前缀。
  • 嗨,史蒂夫。我知道这已经很晚了,但这是一个简短的说明,我终于能够实现您推荐的 Trie 结构并且它工​​作得很好!非常感谢您的帮助。我在下面链接了我的解决方案,请随时查看

标签: python regex algorithm dictionary


【解决方案1】:

因为您提到输入的正则表达式具有word+ 一个简单的单词和一个加号正则表达式符号的结构,您可以使用优化Aho-Corasick 算法 的修改版本,在此算法中您从可以轻松修改的搜索模式中制作一个有限状态机,轻松接受一些正则表达式符号,就像在您的情况下,一个非常简单的解决方案是将您的键填充到列表中最长单词的长度并接受之后的任何内容填充,有一个容易实现的通配符是'.'和 '?',对于*,一个人必须走到单词的末尾或返回并通过列表跟随另一条路径,这可以是常量内存中的指数选择数(任何和所有确定性有限自动机)。

可以在线性时间内生成用于正则表达式键列表的有限状态机,这意味着它所花费的时间与字典键的长度之和成正比。正如here 解释的那样,还支持字典中最长匹配的单词。

【讨论】:

  • 既然“模式”都是前缀,那么有限状态机不自然会以前缀树的形式结束吗?
  • @Stef 重要的一点,荣誉,即使模式不是前缀,FSM 也会以前缀树的形式结束,它只是有一堆额外的边缘来防止重新启动并保持一个来自重新匹配当前匹配的字符,如果可能的话,继续前进到一条路径已经包含以前的字符并且刚刚消耗了一个。所以它本质上是一个前缀树,带有一些额外的辅助边,有助于一些查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多