雪花和正则表达式 - 在 SF 中实现已知良好表达式时的问题

Posted

技术标签:

【中文标题】雪花和正则表达式 - 在 SF 中实现已知良好表达式时的问题【英文标题】:Snowflake and Regular Expressions - issue when implementing known good expression in SF 【发布时间】:2020-09-02 11:17:13 【问题描述】:

我正在寻求有关调试 REGEXP_REPLACE() 语句的帮助。

我一直在使用在线正则表达式编辑器来构建表达式,然后使用 SF regexp_* 函数来实现它们。我试图与 SF 正则表达式实现保持一致,但我看到返回的结果不一致,我希望有人能解释一下:)

我的意图是用新的分隔符 (#^#) 替换文本中的逗号(不包括带有双引号的逗号)。

示例文本字符串:

"Foreign Corporate Name Registration","99999","Valuation Research",,"Active Name",02/09/2020,"02/09/2020","NEVADA","UNITED STATES",,,"123 SOME STREET",,"MILWAUKEE","WI","53202","UNITED STATES","123 SOME STREET",,"MILWAUKEE","WI","53202","UNITED STATES",,,,,,,,,,,,

RegEx 命令和替换(在regex101.com 工作):

([("].*?["])*?(,)
\1#^#

regex101.com 结果:

"Foreign Corporate Name Registration"#^#"99999"#^#"Valuation Research"#^##^#"Active Name"#^#02/09/2020#^#"02/09/2020"#^#"NEVADA"#^#"UNITED STATES"#^##^##^#"123 SOME STREET"#^##^#"MILWAUKEE"#^#"WI"#^#"53202"#^#"UNITED STATES"#^#"123 SOME STREET"#^##^#"MILWAUKEE"#^#"WI"#^#"53202"#^#"UNITED STATES"#^##^##^##^##^##^##^##^##^##^##^##^#

当我尝试使用 REGEXP_REPLACE() 在 SF 中实现相同的逻辑时,我使用的是以下语句:

SELECT TOP 500
    A.C1
    ,REGEXP_REPLACE((A."C1"),'([("].*?["])*?(,)','\\1#^#') AS BASE
FROM
    "<Warehouse>"."<database>"."<table>" AS A

此语句返回 BASE 的结果:

"Foreign Corporate Name Registration","99999","Valuation Research",,"Active Name",02/09/2020,"02/09/2020","NEVADA","UNITED STATES",,,"123 SOME STREET",,"MILWAUKEE","WI","53202","UNITED STATES","123 SOME STREET",,"MILWAUKEE","WI","53202","UNITED STATES"#^##^##^##^##^##^##^##^##^##^##^##^#

正如您在比较结果时所看到的,SF 结果集只是替换了文本末尾的逗号。

谁能告诉我为什么 regex101.com 和 SF 之间的结果使用相同的语句返回不同的结果?我的表达是否不符合 RegEx 的 SF 实现 - 如果是,您能告诉我原因吗?

非常感谢您花时间和精力阅读本文!

周三快乐, 凯西。

【问题讨论】:

【参考方案1】:

使用.*? 实现正则表达式的惰性匹配仅限于 PCRE,Snowflake 不支持。要看到这一点,在 regex101.com 中,将您的“风味”更改为 PCRE (php) 以外的任何内容;您将看到您的 ([("].*?["])*?(,) 正则表达式不再达到您的预期。

我相信这将适用于您的目的:

REGEXP_REPLACE(A.C1,'("[^"]*")*,','\\1#^#')

【讨论】:

以上是关于雪花和正则表达式 - 在 SF 中实现已知良好表达式时的问题的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式:如何在 PL/SQL 中实现负向后查找

如何在没有正则表达式的情况下在 C++ 中实现有效的全字字符串替换?

如何在雪花中使用正则表达式?

从雪花外部阶段选择行时如何使用正则表达式?

java中用正则表达式把字符串“abd 22dfdf Dfd23434sf”变为Abd 22_dfdf Dfd_23434_sf一定要用正则表达式

java中,正则表达式,如何过滤除数字和字母之外的其它字符??