Snowflake SQL正则表达式~提取多个VAL

Snowflake SQL正则表达式~提取多个VAL,sql,regex,snowflake-cloud-data-platform,Sql,Regex,Snowflake Cloud Data Platform,我试图使用Snowflakes regexp\u substr识别嵌套在字符串中的值 我要访问的值在引号中: ... Type: a: - !<string> val: "A" - !<string> val: "B" - !<string> val: "C" ... 这将产生: Type: a: - !<string> val: "A" 虽然这给了字符串的第一部分A,但我只想找到一种分

我试图使用Snowflakes regexp\u substr识别嵌套在字符串中的值

我要访问的值在引号中:

...
Type:
  a:
    - !<string>
     val: "A"
    - !<string>
     val: "B"
    - !<string>
     val: "C"
...
这将产生:

Type: a: - !<string> val: "A"

虽然这给了字符串的第一部分A,但我只想找到一种分别访问A、B和C的方法。

这个select语句将为您提供所需的。。。索塔。您应该注意到,它将查找特定的val出现频率,然后为您提供后面的下一个单词字符

据我所知,正则表达式的计算结果是表达式的第一次出现,因此一旦找到模式,就完成了。您可能希望查看Snowflake JavaScript存储过程,看看是否可以使用下面的示例进行迭代,增加适当的值以生成预期的输出


您必须分两个阶段提取值

提取文档的以下部分,键入:a:包含所有val:数据。 将数据提取为数组或使用REGEXP\u SUBSTR+索引n提取第n个元素 结果是一个数组,您可以在其中使用索引[0]等访问第一个值。
第一个regexp可以缩短为最省力的“类型:\\s++\\w+:[^]+[^]+[^]++”。

再多一个角度-在UDF中使用javascript regex功能

例如:

create or replace function my_regexp(S text)
  returns array
  language javascript
as
$$
  const re = /(\w+)/g
  return [...S.match(re)]
$$
;
以这种方式调用:

set S = '
Type:
  a:
    - !<string>
     val: "A"
    - !<string>
     val: "B"
    - !<string>
     val: "C"
';

select my_regexp($S);
实现完整的正则表达式需要更多的工作,但正如您所见,这绕过了单值限制


也就是说,如果性能是您的首要任务,我希望Snowflake原生正则表达式的支持性能会更好,即使您多次指定正则表达式,尽管我还没有对此进行测试。

您想要所有值的列表还是能够访问第n个值?您似乎很乐意在字符串中使用标记,例如省略号。。。表示任何文本。WARE和val也是表示某物的标记,或者是字符!你的数据中有val吗?是的,还有其他的!和字符串中的val。谢谢你指出这一点。我还希望能够访问第n个值。JavaScript RegExp是真实的,而不是通过SQL函数提供的缩减版本。@making输入中的省略号[…]很可能表示摘录上方和下方的无休止的单词,因此您最终会提取整个文档中的单词。@making只需要以下类型:a:
SELECT
  'Type:\\s+\\w+:((\\s+- !<string>\\s+val:\\s+"[^"]")+)' type_section_rx
  REGEXP_SUBSTR(col, type_section_rx, 1, 1, 'i', 1) vals,
  PARSE_JSON('[0' || REPLACE(vals, REGEXP_SUBSTR(vals, '[^"]+'), ', ') || ']') raw_array,
  ARRAY_SLICE(raw_array, 1, ARRAY_SIZE(raw_array)) val_array,
  val_array[1] B
FROM INPUT_STRING

create or replace function my_regexp(S text)
  returns array
  language javascript
as
$$
  const re = /(\w+)/g
  return [...S.match(re)]
$$
;
set S = '
Type:
  a:
    - !<string>
     val: "A"
    - !<string>
     val: "B"
    - !<string>
     val: "C"
';

select my_regexp($S);
[ "Type", "a", "string", "val", "A", "string", "val", "B", "string", "val", "C" ]