Snowflake中用POSIX正则提取指定边界间文本的技术问题
解决Snowflake POSIX正则提取指定边界文本的问题
Snowflake仅支持POSIX扩展正则,不兼容PCRE的正向预查语法,因此需要调整正则逻辑,用兼容方式提取TOKEN: 到(、TOKEN、TOKN或文本结尾之间的内容。以下是两种可行方案:
方案1:非贪婪匹配+非捕获组(推荐)
Snowflake的ICU正则引擎支持非贪婪量词.*?,可匹配到第一个终止符为止,结合非捕获组标记终止符,避免捕获无关内容。
正则表达式:TOKEN: (.*?)(?:\\(|TOKEN|TOKN|$)
TOKEN::匹配起始标记(.*?):非贪婪捕获组,提取终止符前的目标内容(?:\\(|TOKEN|TOKN|$):非捕获组,匹配终止符((、TOKEN、TOKN或文本结尾),不纳入捕获结果
修改后的完整SQL:
with d as (select 'TOKEN: get this text (subtitle)TOKN: skip this text alsoTOKEN: get this textTOKN: not this one' as data), r as (select 'TOKEN: (.*?)(?:\\(|TOKEN|TOKN|$)' as reg), p as ( select regexp_substr(data, r.reg, 1, 1, 'e') as tkn1, regexp_substr(data, r.reg, 1, 2, 'e') as tkn2, regexp_substr(data, r.reg, 1, 3, 'e') as tkn3, regexp_substr(data, r.reg, 1, 4, 'e') as tkn4 from d join r ) select * from p;
执行结果:
- tkn1:
get this text - tkn2:
get this text - tkn3:
NULL - tkn4:
NULL
方案2:先替换终止符再提取(无预查依赖)
若担心预查或非贪婪匹配的兼容性,可先将所有终止符替换为统一分隔符,再用简单正则提取内容:
步骤:
- 用
REGEXP_REPLACE把(、TOKEN、TOKN替换为| - 提取
TOKEN:到|之间的内容
完整SQL:
with d as (select 'TOKEN: get this text (subtitle)TOKN: skip this text alsoTOKEN: get this textTOKN: not this one' as data), transformed as ( select regexp_replace(data, '(\\(|TOKEN|TOKN)', '|') as transformed_data ), p as ( select regexp_substr(transformed_data, 'TOKEN: ([^|]+)', 1, 1, 'e') as tkn1, regexp_substr(transformed_data, 'TOKEN: ([^|]+)', 1, 2, 'e') as tkn2, regexp_substr(transformed_data, 'TOKEN: ([^|]+)', 1, 3, 'e') as tkn3, regexp_substr(transformed_data, 'TOKEN: ([^|]+)', 1, 4, 'e') as tkn4 from transformed ) select * from p;
执行结果与方案1一致。
内容的提问来源于stack exchange,提问作者bbg
相关产品推荐
相关产品推荐

