雪花SQL,如何向前看直到某个值出现

雪花SQL,如何向前看直到某个值出现,sql,regex,snowflake-cloud-data-platform,Sql,Regex,Snowflake Cloud Data Platform,下面是我正在处理的文本示例 --- info1: * val: "A" --- Type: * answers: * - !<string> * val: "B" * - !<string> * val: "C" --- info2: * val: "D" --- 我正在尝试选择以下文本: Type: * answers: * - !<string> * val: "B" * - !<string> *

下面是我正在处理的文本示例

--- 
info1:
*  val: "A"
---
Type:
*  answers:
*  - !<string>
*    val: "B"
*  - !<string>
*    val: "C"
--- 
info2:
*  val: "D"
---
我正在尝试选择以下文本:

Type:
*  answers:
*  - !<string>
*    val: "B"
*  - !<string>
*    val: "C"
我曾尝试使用“展望未来”,但没有取得多大成功。 REGEXP_SUBSTRcol,“类型:.*--” 在这里,我试图查找,直到下一次出现'--',但我想我误解了它的工作原理。

在本机SQL中的snowflake非常有限,因此当您告诉is通过REGEXP_SUBSTRt匹配多行并匹配新行时,“键入:.*--',1,1,'mes',1 REGEXP是灰色的,因此:

SELECT '--- 
info1:
*  val: "A"
---
Type:
*  answers:
*  - !<string>
*    val: "B"
*  - !<string>
*    val: "C"
--- 
info2:
*  val: "D"
---' as t
,REGEXP_SUBSTR(t, '(Type:.*)',1,1,'mes',1) as r1 
,REGEXP_SUBSTR(t, '(Type:.*)---',1,1,'mes',1) as r2;
给予

你应该能够从中进步


另外,如果您需要非常复杂的regexp,您可以创建一个javascript UDF并使用javascript regexp引擎。

雪花不支持look aheads或look behinds,但它支持组提取和嵌套组提取。这些可以在REGEXP\u REPLACE或REGEXP\u SUBSTR中使用。在本例中,我更喜欢从中提取的REGEXP_SUBSTR,而不是在中替换。在我下面的示例中,您将看到这两种情况

您有3个破折号-用作分隔符,问题是您的数据中有一个破折号。我建议将分隔符替换为数据中不存在的内容,我选择了波浪号~

下面的代码示例将起作用

注:

列C2在保留前导空格列上操作,该列不删除前导空格。在这种情况下,前导空间是第一个捕获组。 列C3对实际数据列进行操作,但假定前导空格是空格、回车符、换行符或垂直空格中的一个或多个。 捕获组:

~[^~]+? - 捕获以波浪号开始的某物~零次或多次,并且在其中 [^~]+-一次或多次捕获非波浪形的任何内容
Snowflake中的正则表达式确实支持负数,但如果要查找多个字符,我倾向于发现它们很难使用,但在本例中,我们有一个字符来对波浪线[^~]求反。

您不需要使用正则表达式前瞻来获取所需的字符串,它只是eg

REGEXP_SUBSTR(col, '(^Type:\\s+(^[*].*$\\s+)*)^---', 1, 1, 'm', 1)
如果您需要带有lookahead等的regexp,请通过函数包装器使用JavaScript regexp,例如

CREATE OR REPLACE FUNCTION RegExp_Match("STRING" VARCHAR, "REGEXP" VARCHAR)
RETURNS VARIANT LANGUAGE JAVASCRIPT STRICT IMMUTABLE AS
'return STRING.match(REGEXP);';
CREATE OR REPLACE FUNCTION RegExp_Match("STRING" VARCHAR, "RX" VARCHAR, "FLAGS" VARCHAR)
RETURNS VARIANT LANGUAGE JAVASCRIPT STRICT IMMUTABLE AS
'return STRING.match(new RegExp(RX, FLAGS));';

SELECT RegExp_Match('<aA>', '(?<=<)(.)\\1(?=>)', 'i');
-- RegExp with lookback, back reference and lookahead ignoring case
=> [ "aA", "a" ]

示例文本中的lossType:或任何/字符在哪里?对不起,应该已更正。现在已经修好了。不知道他们用的是什么正则表达式引擎。以下是几种方法:类型:[\S\S]*:-->$或类型:[\S\S]*??=-->$或?sType:.*=-->$这三种模式都会因无效的正则表达式而失败:“?sType:.*=-->$”,重复运算符没有参数:?这三种模式都会因无效的正则表达式而失败:尝试此类型时得到了什么:[\S\S]*?:——$三者中哪一个?毕竟,只是想克服贪婪,增加一点所有类型的行为。不需要经历分裂旋转。这里似乎确实支持这样一个简单的类型:.*??:--|$将与s修饰符参数's:the'。通配符也与换行符匹配。这三个通配符都有相同的错误,即没有重复运算符的参数:?,但为了让您幽默,无效的正则表达式:'Type:[Ss]*?:-|$',没有重复运算符的参数:?和无效的正则表达式:'Type:.**:-|$',没有重复运算符的参数:?这几乎像是一场战争?不支持重复运算符。但正如我所说,snowflake SQL正则表达式非常简单,如果您需要更复杂的正则表达式,请使用js udf,如下所示:
T   PART    R1
---   info1:  *  val: "A"  ---  Type:  *  answers:  *  - !<string>  *    val: "B"  *  - !<string>  *    val: "C"  ---   info2:  *  val: "D"  ---        
---   info1:  *  val: "A"  ---  Type:  *  answers:  *  - !<string>  *    val: "B"  *  - !<string>  *    val: "C"  ---   info2:  *  val: "D"  ---       info1:  *  val: "A"      
---   info1:  *  val: "A"  ---  Type:  *  answers:  *  - !<string>  *    val: "B"  *  - !<string>  *    val: "C"  ---   info2:  *  val: "D"  ---      Type:  *  answers:  *  - !<string>  *    val: "B"  *  - !<string>  *    val: "C"      Type:  *  answers:  *  - !<string>  *    val: "B"  *  - !<string>  *    val: "C"  
---   info1:  *  val: "A"  ---  Type:  *  answers:  *  - !<string>  *    val: "B"  *  - !<string>  *    val: "C"  ---   info2:  *  val: "D"  ---       info2:  *  val: "D"      
---   info1:  *  val: "A"  ---  Type:  *  answers:  *  - !<string>  *    val: "B"  *  - !<string>  *    val: "C"  ---   info2:  *  val: "D"  ---        
USE ROLE SYSADMIN;
USE WAREHOUSE PUBLIC_WH;
USE UTIL_DB.PUBLIC;

CREATE OR REPLACE TEMP TABLE REGEXP_TEST
AS
SELECT $1::VARIANT AS C1
FROM VALUES 
($$ 
--- 
info1:
*  val: "A"
---
Type:
*  answers:
*  - !<string>
*    val: "B"
*  - !<string>
*    val: "C"
--- 
info2:
*  val: "D"
---
$$);


SELECT C1
    ,REPLACE(C1,'---','~') AS KEEPS_LEADING_SPACE
    ,REGEXP_SUBSTR(KEEPS_LEADING_SPACE,'(~([^~]+))?',1,4,'is') AS C2
    ,REGEXP_SUBSTR(REGEXP_REPLACE(C1,'[\s\r\n\v]?-{3}','~'),'(~([^~]+))?',1,3,'is') AS C3
FROM REGEXP_TEST
;
REGEXP_SUBSTR(col, '(^Type:\\s+(^[*].*$\\s+)*)^---', 1, 1, 'm', 1)
CREATE OR REPLACE FUNCTION RegExp_Match("STRING" VARCHAR, "REGEXP" VARCHAR)
RETURNS VARIANT LANGUAGE JAVASCRIPT STRICT IMMUTABLE AS
'return STRING.match(REGEXP);';
CREATE OR REPLACE FUNCTION RegExp_Match("STRING" VARCHAR, "RX" VARCHAR, "FLAGS" VARCHAR)
RETURNS VARIANT LANGUAGE JAVASCRIPT STRICT IMMUTABLE AS
'return STRING.match(new RegExp(RX, FLAGS));';

SELECT RegExp_Match('<aA>', '(?<=<)(.)\\1(?=>)', 'i');
-- RegExp with lookback, back reference and lookahead ignoring case
=> [ "aA", "a" ]