解析查询字符串的最佳方法

3

我正在为我正在开发的Web应用程序构建一个类似于Jira高级问题搜索中看到的搜索栏的查询组件。这个组件可以进行类似搜索的操作:

https://jira.atlassian.com/browse/WBS-167?jql=status%20%3D%20Accepted

搜索与SQL中的WHERE语句非常相似,但只支持选择性比较运算符(例如,我不打算支持between比较运算符)。首先想到的是使用正则表达式,但我听说SQL是最难用正则表达式解析的第三个东西。 例如,这可能是一个复杂的查询,我希望能够解析: firstName = 'john' OR (lastName = 'doe' AND (status IN (1,3,5) OR type NOT IN (2, 4, 6)) AND username CONTAINS 'd' AND (type = 1 OR status = 2) 并且希望解析此字符串的结果看起来像这样:
[{
  field: 'firstName',
  comparison: '=',
  value: 'john'
}, {
  connector: 'OR',
  items: [{
    field: 'lastName',
    comparison: '=',
    value: 'doe'
  }, {
    connector: 'AND',
    items: [{
      field: 'status',
      comparison: 'IN',
      value: [1,3,5]
    }, {
      connector: 'OR',
      field: 'type',
      comparison: 'NOT IN',
      value: [2,4,6]
    }]
  }]
}, {
  connector: 'AND',
  field: 'username',
  comparison: 'CONTAINS',
  value: 'd'
}, {
  connector: 'AND',
  items: [{
    field: 'type',
    comparison: '=',
    value: 1
  }, {
    connector: 'OR',
    field: 'status',
    comparison: '=',
    value: 2
  }]
}]

如果正则表达式不是一个好的选择(并且尝试使用正则表达式几个小时没有产生任何好的结果),那么尝试解析这种类型的字符串的最佳方法是什么?

4
创建一个半复杂的解析器,首先浮现在脑海中的事情是... 不要使用正则表达式(仅基于您的标签)。也许可以使用Lexx、Yacc、SableCC、ANTLR、Bison等任何带有语法的工具。这可能并不比计算器更复杂,但表达式树仍然非常适用。 - user645280
1个回答

2

看起来你正在开发一种小而简单的语言。正如ebyrod所说,你应该使用基于语法的解析器而不是正则表达式。Lex和Yacc是这项工作的绝佳且易用的工具。根据你使用的语言,有不同的替代方案。

看一下这个

正如你所见,你需要定义所有支持出现在输入中的操作。这是在Lex文件中完成的。然后你需要定义你的句法结构(语法)和最后一步是组合你的输出字符串。


+1 给 ebyrod。我笑了。看起来你链接的那个示例也相当不错。 - user645280
是的,最终我找到了http://zaach.github.io/jison/,并在此处找到了一个jison的SQL文件:https://raw.githubusercontent.com/camilojd/sequeljs/master/src/SqlParser.jison。我打算将jison文件剥离到我需要的基本标记,然后使用语法作为示例来构建自己的语法。 - ryanzec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接