Snowflake SQL 正则表达式 ~ 提取多个值
Snowflake SQL Regex ~ Extracting Multiple Vals
我正在尝试使用 Snowflakes regexp_substr()
来识别嵌套在字符串中的值
我要访问的值在引号中:
...
Type:
a:
- !<string>
val: "A"
- !<string>
val: "B"
- !<string>
val: "C"
...
*这上面和下面有很多文字。
我想提取所有列的 A、B 和 C。但我不确定如何。我曾尝试使用 regexp_substr() 但无法隔离第一个值。
我试过:
REGEXP_SUBSTR(col, 'Type\W+(\w+)\W+\w.+\W+\w.+')
产生:
Type: a: - !<string> val: "A"
虽然这给出了带有 "A" 的字符串的第一部分,但我只想要一种单独访问 "A"、"B" 和 "C" 的方法。
这个 select 语句会给你你想要的......有点。您应该注意到它会查找 "val" 的特定出现,然后为您提供下一个单词字符。
据我所知,REGEX 的计算结果是表达式的第一次出现,所以一旦找到模式,它就完成了。您可能想查看 Snowflake JavaScript 存储过程,看看您是否可以采用下面的示例并进行迭代,增加适当的值以产生预期的输出。
SELECT REGEXP_SUBSTR('Type: a:- !<string>val: "A" - !<string> val: "B" - !<string> val: "C"','val\W+(\w+)', 1, 1, 'e', 1) as A,
REGEXP_SUBSTR('Type: a:- !<string>val: "A" - !<string> val: "B" - !<string> val: "C"','val\W+(\w+)', 1, 2, 'e', 1) as B,
REGEXP_SUBSTR('Type: a:- !<string>val: "A" - !<string> val: "B" - !<string> val: "C"','val\W+(\w+)', 1, 3, 'e', 1) as C;
您必须分两个阶段提取值;
- 提取文档的以下部分类型:a:包含所有
val: "data"
.
- 将
"data"
提取为数组或使用REGEXP_SUBSTR()
+索引n提取第n元素
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
结果是一个数组,您可以在其中访问具有索引 [0]
等的第一个值。
第一个正则表达式可以缩短为 "least effort" 'Type:\s+\w+:(([^"]+"[^"]+")+)'
.
另一个角度 -- 在 UDF 中使用 javascript 正则表达式功能。
例如:
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" ]
实现完整的正则表达式需要多做一些工作,但如您所见,这绕过了单值限制。
就是说,如果性能是您的首要任务,我希望 Snowflake 本机正则表达式支持表现出色,即使您多次指定正则表达式,但我还没有对此进行测试。
我正在尝试使用 Snowflakes regexp_substr()
来识别嵌套在字符串中的值我要访问的值在引号中:
...
Type:
a:
- !<string>
val: "A"
- !<string>
val: "B"
- !<string>
val: "C"
...
*这上面和下面有很多文字。
我想提取所有列的 A、B 和 C。但我不确定如何。我曾尝试使用 regexp_substr() 但无法隔离第一个值。 我试过:
REGEXP_SUBSTR(col, 'Type\W+(\w+)\W+\w.+\W+\w.+')
产生:
Type: a: - !<string> val: "A"
虽然这给出了带有 "A" 的字符串的第一部分,但我只想要一种单独访问 "A"、"B" 和 "C" 的方法。
这个 select 语句会给你你想要的......有点。您应该注意到它会查找 "val" 的特定出现,然后为您提供下一个单词字符。
据我所知,REGEX 的计算结果是表达式的第一次出现,所以一旦找到模式,它就完成了。您可能想查看 Snowflake JavaScript 存储过程,看看您是否可以采用下面的示例并进行迭代,增加适当的值以产生预期的输出。
SELECT REGEXP_SUBSTR('Type: a:- !<string>val: "A" - !<string> val: "B" - !<string> val: "C"','val\W+(\w+)', 1, 1, 'e', 1) as A,
REGEXP_SUBSTR('Type: a:- !<string>val: "A" - !<string> val: "B" - !<string> val: "C"','val\W+(\w+)', 1, 2, 'e', 1) as B,
REGEXP_SUBSTR('Type: a:- !<string>val: "A" - !<string> val: "B" - !<string> val: "C"','val\W+(\w+)', 1, 3, 'e', 1) as C;
您必须分两个阶段提取值;
- 提取文档的以下部分类型:a:包含所有
val: "data"
. - 将
"data"
提取为数组或使用REGEXP_SUBSTR()
+索引n提取第n元素
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
结果是一个数组,您可以在其中访问具有索引 [0]
等的第一个值。
第一个正则表达式可以缩短为 "least effort" 'Type:\s+\w+:(([^"]+"[^"]+")+)'
.
另一个角度 -- 在 UDF 中使用 javascript 正则表达式功能。
例如:
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" ]
实现完整的正则表达式需要多做一些工作,但如您所见,这绕过了单值限制。
就是说,如果性能是您的首要任务,我希望 Snowflake 本机正则表达式支持表现出色,即使您多次指定正则表达式,但我还没有对此进行测试。