使用Ruby从SQL中删除注释

时间:2014-11-07 21:20:36

标签: ruby

我想转此:

sql = <<-SQL
  DROP TABLE IF EXISTS ABC;
  --My comments
  SELECT 1 AS A
SQL

进入这个:

sql = <<-SQL
  DROP TABLE IF EXISTS ABC;
  SELECT 1 AS A
SQL

这就是我所拥有的:

sql = sql.split("\n").reject { |i| i.strip.start_with?("--") }.join("\n")

我希望有一些其他内置的方法,如果可能的话,也可以涵盖多行/*...*/评论。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

你做得太难了:

sql = <<-SQL
  DROP TABLE IF EXISTS ABC;
  --My comments
  SELECT 1 AS A
SQL

sql.lines.reject{ |l| l.lstrip[/^--/] }.join # => "  DROP TABLE IF EXISTS ABC;\n  SELECT 1 AS A\n"

由于换行符很有用,因此无需在"\n"上拆分。相反,lines执行类似的操作,只返回具有尾随换行符的行。 lstrip可让您轻松查看--是否是第一件事。 join将生成的数组转换回字符串,并且尾随换行符也会继续运行。

尝试剥离多行块注释的方式要困难得多,所以我采取了不同的方法。删除单行注释后,我会执行以下操作:

sql = <<-SQL
  DROP TABLE IF EXISTS ABC;
  /* 
  My comments
  */
  SELECT 1 AS A
SQL

stripped = sql.lines.reject{ |l|
  if l['/*'] .. l['*/']
    true
  else
    false
  end  
}
stripped # => ["  DROP TABLE IF EXISTS ABC;\n", "  SELECT 1 AS A\n"]

魔术是..,这就是&#34;触发器&#34;运算符,并且非常适合这种情况,在这种情况下,您希望找到某事物的开头,然后结束它。当l['/*']找到匹配项时会发生什么,..会记住匹配并开始返回true。 l['*/']匹配后,..开始再次返回false。好像是

l['/*'] .. l['*/']

可以单独工作,但Ruby需要看到条件测试,如if,以了解..是触发器还是范围运算符。这是..的两种用法之间令人遗憾的碰撞,很多人都不喜欢它,但这并不是避免它的好理由。

关于..的这种使用的有趣讨论是在#34; Remove flip-flops in 2.0&#34;。我个人不同意任何摆脱运算符的举动,因为它的功能对于这种情况非常有用,并且用纯Ruby代码替换它看起来更加混乱,但也许这是因为我已经使用它很长时间了Ruby和Perl。