将ORDER BY语句拆分为数组

时间:2010-06-22 01:03:17

标签: ruby regex

我试图将SQL查询的ORDER BY语句拆分为数组。第一个倾向是:

order_by.split(',')

但是这不适用于以下语句的顺序:

SUBSTRING('test',1,3) ASC, SUBSTRING('test2', 2,2 ) DESC

上述陈述的理想输出是:

["SUBSTRING('test',1,3) ASC", "SUBSTRING('test2', 2,2 ) DESC"]

我相当肯定如果我可以匹配任何未包含在parethesis中的逗号,它会起作用,但我无法找到在ruby正则表达式中执行此操作的方法,因为不支持lookbehind。

3 个答案:

答案 0 :(得分:1)

最简单的方法是使用preg_replace_callback将括号替换为占位符,然后展开数据,然后循环并放回括号。

答案 1 :(得分:0)

虽然我怀疑可能还有一种方法可以使用正则表达式,但你也可以通过简单的字符串解析来实现。

查找字符串中的所有逗号,然后从该点开始向前或向后(如果括号正确平衡,则无关紧要),为开括号添加一个,为闭括号减去一个。如果你最后没有0,你就在一个大括号内,所以它不是你想要的逗号。

拆分所有其他逗号。

编辑

虽然有关此方法的注释在逗号括起的括号中失败是有效的,但可能是您处理简单的查询而不用担心。如果是这种情况,这应该有效:

def in_brackets(str,pos)
  cnt = 0
  str[pos,str.length].each_char do |c|
    if c == '('
      cnt += 1
    elsif c == ')'
      cnt -= 1
    end
  end

  return cnt != 0
end

def split_on_some_commas(str) 
  offset = -1
  split_pts = []

  while (offset = str.index(",",offset+1))
    if !in_brackets(str,offset)
      split_pts << offset
    end
  end

  split_pts << str.length

  pos = 0

  ret = []
  split_pts.each do |pt|
    ret << str[pos..(pt-1)].strip
    pos = pt+1
  end

  return ret
end

puts split_on_some_commas("SUBSTRING('test',1,3) ASC, SUBSTRING('test2', 2,2 ) DESC, SUBSTRING('test2', 2,2 ) DESC").inspect

答案 2 :(得分:0)

通常,您不能使用正则表达式来解析非常规语言。

尝试使用Rockit为您需要的SQL子集创建真正的语法和解析器。