【问题标题】:Java - Fast regex to find words in textJava - 快速正则表达式在文本中查找单词
【发布时间】:2017-01-26 16:35:54
【问题描述】:

我有一组预定义的单词,例如谋杀、犯罪、警官、抢劫、罪魁祸首、事故、事故、撞车、死亡……(大约 5000 个单词)

我想在一篇新闻文章(大约 1kb-5kb 文本)中匹配这些词,如果找到,然后对这些词进行相应的分类。最初我只是在单词之前和之后使用空格,即

if(article.contains(" "+word+" ")) { \*do something*\ }

但是当单词后跟句号,逗号或其他符号时,这不起作用,单词开头也是如此

所以我切换到带有单词边界的正则表达式,但现在代码运行速度慢了 20 倍,并且 CPU 使用率在 5 个线程中达到 100%。

有没有人在java中有更好的解决方案?感谢所有帮助:)

【问题讨论】:

  • 它也会匹配包含的单词,即'con'和'constable'是不同的单词'con'不应该匹配文本中的'constable'。
  • 您首先需要确定算法,然后寻找 Java 中的实现,例如见here
  • 这个问题stackoverflow.com/questions/225337/…的答案可能有用。
  • 有为matching multiple patterns at the same time设计的算法。如果我是你,我会选择其中之一。请记住(至少在英语中),找到单词的边界并非易事,因为有些单词可能以撇号合法结束(并且半合法地开始)。

标签: java regex optimization text


【解决方案1】:

您将始终需要检查单词中是否包含特殊符号,因此我建议使用 \W 调用 replaceAll 函数以消除单词中的任何多余绒毛/符号(如果确实存在)。

String wordToLookup = " " + word.replaceAll("\\W", "") + " ";
if(article.contains(wordToLookup))
{
    //do something
}

【讨论】:

    【解决方案2】:

    我不认为正则表达式是处理该搜索的最佳工具,但如果您没有找到更好的工具,您已经可以通过制作优化的正则表达式来赢得大量时间。如果你检查that test,我只用了几个令牌和一个小的搜索字符串,单个模式的搜索已经比多个模式的搜索快 4 倍。

    现在显然有 5000 个令牌,我不希望您手动生成和维护该正则表达式,但可以将令牌列表转换为前缀树,然后用于制作正则表达式:

    tokens : con, conman, constitution, correct, exact
    
    tree :     ^
            c     e
            o     x
         n    r   a
      s  $ m  r   c
      t    a  e   t
      i    n  c   $
      t    $  t
    [...]     $
    
    regex : \\b(co(n(stitution|man)?|rrect)|exact)\\b
    

    无论如何,我认为您的第一步应该是研究现有的全文搜索库,这可能会更有效地解决您的问题,而无需付出太多努力。

    【讨论】:

    • 感谢您的示例,创建前缀树是个好主意,但是我现在没有那么多时间。但是我会先检查一些全文匹配引擎是否可以解决问题。
    • 创建前缀树并不难,因为我确信有相应的库。我认为从中创建正则表达式将是困难的部分,尽管如果标记只是文本并且您不介意直接实现完美优化,您可以很容易地获得基本的正则表达式。我可能会尝试一下:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2022-08-18
    相关资源
    最近更新 更多