我有一个字符串:
CREATE TABLE foobar (
bar foo,
foo bar
) DISTRIBUTED BY
我想从此字符串中获取所有列定义。我试过了:
my_string.scan /CREATE TABLE .*\n([^\n]*?)\n.*DISTRIBUTED BY/
但它没有返回所需的值(["bar foo,", "foo bar"]
)。有任何想法吗?
答案 0 :(得分:3)
scan方法的关键点是每个新匹配从最后一个结束时开始:
a = "cruel world"
a.scan(/.../) #=> ["cru", "el ", "wor"]
因此,您需要定义模式,使其在字符串的开头和中间都匹配。毋庸置疑,构建这样的后视表达并不容易。
但我想知道这对你的具体目标是否足够:
s = <<HR
CREATE TABLE foobar (
bar foo,
foo bar
) DISTRIBUTED BY}
HR
ax = s.scan /\s+(.+?)(?:,\n|\n\))/
#=> [["bar foo"], ["foo bar"]]
如您所见,我没有尝试在此处匹配CREATE TABLE
,假设字符串已准备好查询。
答案 1 :(得分:1)
我认为这就是你想要的:
/CREATE TABLE .*\n((?:.*\n)+).*DISTRIBUTED BY/
(?:.*\n)
匹配单个行,因此((?:.*\n)+)
会捕获组#1中的一行或多行。包含了最后一行(foo bar
)末尾的换行符,但您可以在清除逗号的同时删除该换行符(例如来自bar foo,
)。
如果您正在考虑做更复杂的事情,请考虑使用实际的解析器;正则表达式与SQL不兼容。
答案 2 :(得分:0)
可能这是要走的路。
my_string.split[1..-2].map(&:strip)