用于设计查询语言的正则表达式

时间:2014-02-22 17:18:36

标签: javascript regex

最近我们的团队希望建立自己的查询语言,但我们遇到了关于regexp

的问题

如果我们在下面有查询

select A where B skip C limit D

关键字“where”,“skip”和“limit”可以有1或0,这意味着我们也可以有一个像

这样的查询
select A where B skip C
select A skip C limit D
select A limit D

重点是我们想知道是否可以定义一个可以匹配此查询并捕获A,B,C和D的“单个”正则表达式?

这是我们现在的工作方式......

dql_parser.parse = function(str) {
var reg_arr = []
if(str.toLowerCase().indexOf('select') !== -1) {
    var reg = new RegExp(/select\s+(.*?)(limit|where|skip)/i)
    var exe = reg.exec(str)
    if(exe !== null) {
        reg_arr.push('fields=' + exe[1])
    }else {
        var reg = new RegExp(/select\s+(.*)?/i)
        var exe = reg.exec(str)
        reg_arr.push('fields=' + exe[1])
    }
}



if(str.toLowerCase().indexOf('where') !== -1) {
    var reg = new RegExp(/where\s+(.*?)(select|limit|skip)/i)
    var exe = reg.exec(str)
    if(exe !== null) {
        reg_arr.push('selector=' + exe[1])
    }else {
        var reg = new RegExp(/where\s+(.*)?/i)
        var exe = reg.exec(str)
        reg_arr.push('selector=' + exe[1])
    }
}

if(str.toLowerCase().indexOf('skip') !== -1) {
    var reg = new RegExp(/skip\s+(.*?)(select|limit|where)/i)
    var exe = reg.exec(str)
    if(exe !== null) {
        reg_arr.push('skip=' + exe[1])
    }else {
        var reg = new RegExp(/skip\s+(.*)?/i)
        var exe = reg.exec(str)
        reg_arr.push('skip=' + exe[1])
    }
}

if(str.toLowerCase().indexOf('limit') !== -1){
    var reg = new RegExp(/limit\s+(.*?)(select|where|skip)/i)
    var exe = reg.exec(str)
    if(exe !== null) {
        reg_arr.push('limit=' + exe[1])
    }else {
        var reg = new RegExp(/limit\s+(.*)?/i)
        var exe = reg.exec(str)
        reg_arr.push('limit=' + exe[1])
    }

}

return reg_arr;

}

任何建议都表示赞赏。

3 个答案:

答案 0 :(得分:3)

这不是您问题的直接答案,但可能有所帮助。

我建议您使用PEG:解析器生成器。 您将在看起来像BNF的东西中定义您的语言,然后它将为您生成解析器。

这是一个非常可靠的工具,比regexp强大得多,并且非常容易使用,特别是对于像你这样的简单DSL。

答案 1 :(得分:1)

长答案

您想“设计自己的查询语言”,并决定使用RegEx ???

进行解析

嗯...... 没有

编写一个“真正的”解析器是唯一的方法,如果你不能应对挑战,也许你应该放弃这个想法。

如果你真的想这样做,那么先研究一下Flex and Bison(Lex / Yacc,老实说,我不知道他们叫什么了)。这是真正的交易(至少这是我的首选工具包,如果你“投资”它,从长远来看肯定会付出代价。)

祝你好运! ; - )

答案 2 :(得分:0)

但如果你真的,在你的日子里真的想要这样的痛苦:

(select\s+(\w*))\s+(where\s+(\w*))?\s*(skip\s+(\w*))?\s*(limit\s+(\w*))?

会给你A,B C和D. 祝你好运!