【问题标题】:Regex, ANTLR or any other solution?正则表达式、ANTLR 或任何其他解决方案?
【发布时间】:2012-04-08 20:10:40
【问题描述】:

现在这个对我来说是一个很大的挑战。

我在一个文件中有大约 1000 个查询,所有类似的模式如下:

***\*XYZ#PQR#\****

现在,其中 # 表示任意数量的非空白字符。
我已经编写了一段代码,可以读取上述行并生成相应的正则表达式。
但是,大约有 100,000 名候选人,正如我提到的那样,大约有 1000 个此类查询要针对匹配进行评估。
这使我的代码在计算上非常昂贵,因为它的数量级为 m*n。

我已经通过 ANTLR,发现学习曲线非常陡峭。虽然这听起来很有希望,但我仍然怀疑是否可以通过使用 Antlr 来实现。请让我知道您的意见或任何其他可行的解决方案。

【问题讨论】:

  • 您能否更详细地解释一下什么是模式(相同长度、不同长度等)以及您需要对它们做什么。
  • 这些模式旨在处理关键字的变体,例如“*Telecom#Servic#*”将匹配“电信服务”。模式长度可能因关键字而异。我想识别每个变体及其对应的模式。

标签: java regex parsing antlr lexer


【解决方案1】:

在我看来,您拥有数以千计的单个正则表达式,r1, r2, ... r1000,它们标识了结果 A、B、C 的一些固定集合(远小于单个正则表达式的数量) , ...

在这种情况下,您可以将结果 A 的正则表达式 a1, a2, ... an 和结果 B 的 b1, ... bm 逻辑组合。是正则表达式的一个众所周知的理论性质)。

大多数表达正则表达式的系统(可能不是你的)允许你把它写成

 a1 | a2 | .. | an --> A

或一些等效的语法。这样的系统通常与所谓的lexer generators 相关联,它允许编译器编写者用字符来表达标记的细粒度语法。

此类工具的一大优势在于,匹配(所有正则表达式)标记的工作通常次线性相对于正则表达式的数量,通过计算一个有限-状态机,其中由一组正则表达式共享的前缀对于该组只被识别一次。这可能意味着巨大的加速并直接适用于您的情况。

广泛使用的工具 FLEX 非常有效地完成了这项工作。 ANTLR 有某种机制来识别表示为正则表达式的标记,但我不知道它是否会生成有效的有限状态匹配器。

【讨论】:

  • 谢谢。但我的时间线很短,我通过 Lucene 完成了。
【解决方案2】:

完成了。 使用正则表达式,花了一个小时, 使用 Lucene、WildCardQueries 和 booleanQuery 来处理排列,工作在 11 分钟内完成。 *希望有人可以在一周内制定学习 Flex 的时间表。 但是 Lucene 是大型数据集、Regex 和 Crunching 的不错选择。 它可能并不总能解决您的问题,但它只是另一种解决方案。

【讨论】:

    【解决方案3】:

    我认为在 ANTLR 中没有必要,因为可以进行简单的字符串查找和替换:# -> \\.*。应删除星号。

    所以对于*Telecom#Servic#*,你得到了Telecom\\.*Servic\\.*。您还可以添加 $ 和 ^ 来检查字符串的开头/结尾。

    【讨论】:

    • 我已经实现了相同的。然而,它变得相当昂贵。就像我说的那样,我有 1000 个这样的查询。因此,我必须通过 100,000 名候选人运行 1000 次。
    • 这样生成的正则表达式将类似于 ^.*\\s+Telecom\\S*\\s+Servic\\S*\\s+.*$
    • 那么目标是什么?通过消除一些其他正则表达式覆盖的正则表达式来减少正则表达式的数量?
    猜你喜欢
    • 2014-11-09
    • 2018-11-21
    • 1970-01-01
    • 2015-10-25
    • 2010-10-25
    • 1970-01-01
    • 2013-09-29
    • 2023-03-14
    • 2011-03-14
    相关资源
    最近更新 更多