转义动态生成的正则表达式

问题描述

我正在动态创建一个将用作正则表达式模式的字符串。我正在创建它,并在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
)