【发布时间】:2011-07-05 20:49:51
【问题描述】:
为了放弃阅读整个问题,我的基本问题是:
PostgreSQL 中有一个函数可以转义字符串中的正则表达式字符吗?
我查阅了文档,但找不到这样的功能。
这是完整的问题:
在 PostgreSQL 数据库中,我有一列具有唯一名称。我还有一个过程,它会定期将名称插入此字段,并且为了防止重复,如果它需要输入一个已经存在的名称,它会在末尾附加一个空格和括号。
即姓名、姓名(1)、姓名(2)、姓名(3)等
就目前而言,我使用以下代码来查找要添加到系列中的下一个数字(用 plpgsql 编写):
var_name_id := 1;
SELECT CAST(substring(a.name from E'\\((\\d+)\\)$') AS int)
INTO var_last_name_id
FROM my_table.names a
WHERE a.name LIKE var_name || ' (%)'
ORDER BY CAST(substring(a.name from E'\\((\\d+)\\)$') AS int) DESC
LIMIT 1;
IF var_last_name_id IS NOT NULL THEN
var_name_id = var_last_name_id + 1;
END IF;
var_new_name := var_name || ' (' || var_name_id || ')';
(var_name 包含我要插入的名称。)
这暂时可行,但问题在于WHERE 语句:
WHERE a.name LIKE var_name || ' (%)'
此检查无法验证所讨论的 % 是一个数字,并且它不考虑多个括号,例如“名称 ((1))”,如果任何一种情况都存在,则进行强制转换会抛出异常。
WHERE 声明确实需要更像:
WHERE a.r1_name ~* var_name || E' \\(\\d+\\)'
但是var_name 可能包含正则表达式字符,这导致了上面的问题:PostgreSQL 中是否有一个函数可以转义字符串中的正则表达式字符,所以我可以这样做:
WHERE a.r1_name ~* regex_escape(var_name) || E' \\(\\d+\\)'
非常感谢任何建议,包括可能对我的重名解决方案进行修改。
【问题讨论】:
-
我意识到这个问题很老了,但是在搜索 Postgres 函数以转义特殊的正则表达式字符时,它不断出现。所以我添加了一个提供 that 的答案。
标签: regex postgresql escaping pattern-matching plpgsql