【问题标题】:Parse user-input concerning search criteria解析有关搜索条件的用户输入
【发布时间】:2009-11-24 12:41:29
【问题描述】:

我正在寻找一种方法来解析一些用户输入。输入应显示必须执行哪些搜索以及如何组合它们。

  • 1 和 2
  • (3 和 2)或 1
  • (3 与 2)或(1 与 4)
  • ( (3 OR 4) AND 1) OR 2

第一个示例应该以 AND 方式组合搜索 1 和 2 的结果。第二个示例应以 AND 方式组合搜索 3 和 2 的结果,并将此组合的结果以 OR 方式组合到搜索 1 的结果。等等。

关于如何做到这一点的任何想法?

【问题讨论】:

    标签: java search parsing user-input


    【解决方案1】:

    把你的“结果”想象成一个对象,它在下面的接口中提供了和或类似的方法:

    public interface AndOrCapable<T> {
      public T and(T anOtherResult);
      public T or(T anOtherResult);
    }
    

    然后您可以将您的用户输入翻译成如下内容:

    Result total = r2.or(r1.and(r3.or(r4))); // your fourth example
    

    这只是为了澄清这个概念 - 在您的情况下,您需要一个动态评估器,因为您使用用户输入。

    因此,您仍然需要一个验证器/解析器来将用户输入转换为(语法)树,这将是您用来计算总数的模型。

    希望对你有所帮助!

    【讨论】:

      【解决方案2】:

      JavaCC 是用于为此生成解析器的好工具。或者,如果您可以稍微更改语法,则可以使用方案解释器使用 java 的脚本工具,例如

      ( (3 OR 4) AND 1) OR 2
      

      变成

      (OR (AND (OR 3 4) 1) 2)
      

      那么你只需要实现 AND/OR

      【讨论】:

        【解决方案3】:

        干净的解决方案是编写一个中缀解析器;网上有很多代码示例。但是,在您的示例中,一个更简单的算法可能就足够了,因为您不需要运算符优先级等。

        作为编码说明:StreamTokenizer 类可能会帮助您解析输入字符串。

        【讨论】:

          【解决方案4】:

          在实现端(一旦你有了解析器,组织和执行搜索):

          1. 创建一个Condition 树怎么样,其中Condition 对象可能是简单条件,或者是用布尔值连接两个简单条件的复合条件(IE ANDCondition 父节点与子节点RangeConditionEqualsCondition)。

            然后您根据每个项目评估树的顶部。这个解决方案是 O(mn),其中 m 是条件数,n 是要搜索的项目数,但您可以通过删除冗余条件来优化它。如果第一个条件消除了大多数项目,则速度会快得多。

          2. 版本 2:为每个项目分配一个唯一键(例如,数组索引),并为每个条件执行搜索,为每个条件构建一个 HashSet&lt;Key&gt;。然后,从最小的 必需 键集开始,为每个条件删除或添加键,直到获得最终结果。这可能比上述更快,具体取决于。

          注意:这些方法模拟了 SQL 数据库的运行方式——如果您的系统足够大或足够复杂,您可能应该使用数据库进行调查,而不是编写自己的代码来做同样的事情。

          【讨论】:

            【解决方案5】:

            只是关于如何为通用关键字搜索创建解析器的一些灵感......

            即使您标记了问题 java,这里还是一个 Python 中的 searchparser 示例。它使用 pyparsing,一个解析器生成器,它接受一个语法并创建代码,可以运行这些代码来解析用户输入。

            https://github.com/pyparsing/pyparsing/blob/master/examples/searchparser.py

            293 行代码,包括一个测试套件。也许它可以帮助你作为一个起点......

            【讨论】:

            • 虽然它对这个问题“没有帮助”,但答案是好的,你不应该失去它的声誉。我建议标记答案社区 Wiki,所以它不算数。 (顺便说一句 - 我不是在否决答案)
            • Pyparsing 不再托管在 wikispaces.com 上。转至github.com/pyparsing/pyparsing
            猜你喜欢
            • 2015-01-06
            • 2021-05-23
            • 2016-12-17
            • 2017-04-16
            • 2019-03-21
            • 2021-11-23
            • 2017-02-28
            • 1970-01-01
            • 2015-11-25
            相关资源
            最近更新 更多