Java 正则表达式的替代方案

Java 正则表达式的替代方案,java,regex,parsing,Java,Regex,Parsing,我有一组嵌入数字的字符串。它们看起来像/cal/long/3/4/145:999或/pa/metrics/CosmicRay/24:4:bgp:EnergyKurtosis。我想要一个表达式解析器,它是 易于使用。举几个例子,有人应该能够形成一个新的表达。我希望最终用户能够形成新的表达式来查询这组字符串。一些潜在用户是软件工程师,另一些是测试人员,还有一些是科学家 允许对数字进行限制。类似“/cal/long/3/4/143:#>100&没有理由重新发明轮子!正则表达式引擎的核心是建立在数学和

我有一组嵌入数字的字符串。它们看起来像/cal/long/3/4/145:999或/pa/metrics/CosmicRay/24:4:bgp:EnergyKurtosis。我想要一个表达式解析器,它是

  • 易于使用。举几个例子,有人应该能够形成一个新的表达。我希望最终用户能够形成新的表达式来查询这组字符串。一些潜在用户是软件工程师,另一些是测试人员,还有一些是科学家

  • 允许对数字进行限制。类似“/cal/long/3/4/143:#>100&没有理由重新发明轮子!正则表达式引擎的核心是建立在数学和计算机科学的坚实基础上;我们今天继续使用它们的原因是它们基本上是可靠的,在可预见的未来不会得到改进


    如果您确实找到或创建了一些只包含Regex可以实现的可能性的子集的替代解析语言,您很快就会有一个用户要求一个可以用Regex表达的概念,但您的风格完全被忽略了。把时间花在解决尚未解决的问题上

    实际上,您描述的是Java Matcher。它恰好使用正则表达式作为它的语言

    不幸的是,并不是所有的程序员(包括我自己)都像他们应该的那样熟悉正则表达式。这通常意味着我们最终要编写自己的字符串解析逻辑,否则正则表达式本可以很好地为我们服务


    这并不总是坏事。在某些情况下,可以编写更优雅、可读性更强的DSL(一个类,一组内聚的方法),并满足您的问题领域的精确需求。问题在于,将问题提炼成简单直观的DSL可能需要几十次迭代。只有当DSL在应用程序或大型社区中广泛使用时,这一问题才有理由解决。不要为一个只偶尔出现的问题编写一个优雅的解决方案。

    我倾向于同意Rex m,尽管您对数值约束的第二个要求使事情变得复杂。除非您只允许非常基本的约束,否则我不知道如何用正则表达式简洁地表达它。如果有这样一种方法,请忽略我的其余答案,并遵循此处的其他建议。:)

    你可能想考虑一个分析器生成器——比如经典的LeX和YACC。我对Java的选择不是很熟悉,但这里有一个列表:

    如果您不熟悉,标准方法是首先创建一个将字符串转换为令牌的。然后将这些标记传递给解析器,解析器将语法应用于这些标记并输出某种结果

    在您的例子中,我设想解析器将产生正则表达式和附加条件的组合。对于数值约束示例,它可能会为您提供正则表达式
    \/cal/long/3/4/143:(\d+)\
    ,以及应用于第一个分组(要求数字介于100和1100之间的
    \d+
    部分)的约束。然后将RE应用于候选字符串,并将约束应用于这些候选字符串以查找匹配项


    这是一个相当复杂的方法,所以希望有一个更简单的方法。我希望这至少能给你一些想法。

    Java约束是一个严重的约束。我建议使用解析组合符,但您必须使用类而不是函数将这些思想转换为Java。有很多很多关于这个话题的论文;最简单的方法之一是。Hutton的方法特别容易根据数字的大小等条件来决定成功或失败,如您在示例中所示。

    如果您要选择解析器路线,请查看GOLD解析系统。它通常比YACC更好,比纯正则表达式更干净,并且支持Java


    这就是正则表达式的设计目的。我不太明白为什么您需要正则表达式的替代品。如果你能解释一下,也许会帮助我们给出一个好的答案。我的建议是只使用适合您需要的正则表达式子集;我明白了#列表中的2超出了大多数普通正则表达式引擎的范围。:)确切地说,对数字的限制使使用普通正则表达式变得困难。否则我只会使用它们,不会问这些问题。:)据我所知,没有办法扩展或更改模式使用的语法。我不明白为什么你会想,但你应该能够将变量拉到模式中,这将扩展它。Java模式匹配器是最有效的正则表达式工具之一。java中有太多不好的东西需要改变,以致于无法与其中一个伟大的人相处。正则表达式在数学上既可靠又快速。但就易用性和可维护性而言,它们真的很糟糕。在这方面,他们完全是邪恶的。这就是为什么有理由重新发明的原因。@BT这可以用在任何不熟悉的语言上。我不同意。正则表达式至少过于简洁,难以阅读。我相信这是一种观点,但我已经学会了它们,忘记了它们,重新学习了它们。看看lex/yacc是如何使用正则表达式的,它是由命名组件构建的。与用一个可怕的perl风格的regexp编写所有内容相比,这是一种更好的方法。@RexM:您有5秒钟的时间阅读一行Regex并告诉我它的功能。你准备好了吗?开始:
    ()
    。阅读regex就像阅读assembly:是的,这是可能的,但不,你不应该这样做。我很惊讶还没有更高、更可读的语言构建在正则表达式之上。