0

我有一个像这样的字符串:

CREATE TABLE foobar (
   bar foo,
   foo bar
) DISTRIBUTED BY

我想从此字符串中获取所有列定义。我试过:

my_string.scan /CREATE TABLE .*\n([^\n]*?)\n.*DISTRIBUTED BY/

但它不会返回所需的值 ( ["bar foo,", "foo bar"])。有任何想法吗?

4

3 回答 3

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此处进行匹配,假设字符串已准备好查询。

于 2012-09-17T15:16:04.997 回答
1

我认为这就是你想要的:

/CREATE TABLE .*\n((?:.*\n)+).*DISTRIBUTED BY/

(?:.*\n)匹配单个行,因此((?:.*\n)+)捕获组 #1 中的一个或多个行。包括最后一行末尾的换行符 ( foo bar),但您可以在清理逗号的同时删除它(例如 from bar foo,)。

如果您正在考虑做更复杂的事情,请考虑使用实际的解析器;正则表达式不能很好地与 SQL 配合使用。

于 2012-09-17T15:08:40.843 回答
0

大概这就是要走的路。

my_string.split[1..-2].map(&:strip)
于 2012-09-17T16:05:41.160 回答