解析像string这样的查询的最佳方法

时间:2014-04-01 19:36:09

标签: sql regex parsing

所以我正在构建一个类似于我正在处理的Web应用程序的搜索组件的查询,类似于Jira预先搜索问题的搜索栏:

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

搜索基本上与SQL中的WHERE语句非常相似,但仅支持选定的一组比较运算符(例如,我不打算支持比较运算符之间)。首先想到的是使用正则表达式,但我听说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
  }]
}]

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

1 个答案:

答案 0 :(得分:2)

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

看看this

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