问题描述
我正在动态创建一个将用作正则表达式模式的字符串。我正在创建它,并在SNowflake sql中使用它。我想保留其中的保留正则表达式字符作为原始文本的一部分。例如:
'word1,word2,a.b.c,hot/cool,| general'
我将把那些逗号转换为|
,以便我们搜索文本,如果文本中有任何逗号,则得到正匹配。 | general
在文本中也可能合法,因此需要对此进行转义。 .
,/
和许多其他保留字符在文本中。基本上,我需要全部逃避。我将在单独的步骤中进行此转换,因此可以在转义步骤之后将逗号转换为管道。
这是我能想到的最简单的测试用例和解决方案:
select regexp_replace(
'+ . * ? ^ $,[ ] { } ( ) | /',-- text to escape
'\\+|\\.|\\*|\\?|\\^|\\$|\\,|\\[|\\]|\\{|\\}|\\(|\\)|\\||\\/',-- pattern
'\\\\$0' -- replace captured text with \\ in front of it
)
即使在这种情况下,我也会丢失原始文本中的\
,因为它会引发错误。结果是:
\$0 \$0 \$0 \$0 \$0 \$0 \$0 \$0 \$0 \$0 \$0 \$0 \$0 \$0 \$0
在$ 0之前,我尝试了多种反斜杠,但没有任何效果。
Python具有re.escape()
函数。 Javascript有做到这一点的方法(https://stackoverflow.com/a/3561711/1884101)。除了UDF,我无法在SNowflake中找到其他方法来解决这个问题,我非常想避免。有人在Postgres中尝试了我的示例,并且成功了。
在SNowflake sql中是否可以做到这一点(包括转义\
)?
解决方法
显然,regexp_replace函数在各种数据库上具有一些不同的功能。在雪花上,效果很好
select REGEXP_REPLACE(
'+ . * ? ^ $,[ ] { } ( ) | /','\\+|\\.|\\*|\\?|\\^|\\$|\\,|\\[|\\]|\\{|\\}|\\(|\\)|\\||\\/',-- escaped reserved characters
'\\\\\\\\\\0' -- I want to add \\ in front of every reserved character
)
4个反斜杠可以替换为1,这就是为什么要添加两个反斜杠,即4 * 2 = 8(反斜杠)。
获取匹配的模式\\0
你能试试吗
select regexp_replace(
'+ . * ? ^ $,-- text to escape
'\\+|\\.|\\*|\\?|\\^|\\$|\\,-- pattern
'\\\\\\\\$0' -- replace captured text with \\ in front of it
)