要“转义”字符串,您必须“执行”它 - 从字面上看。使用EXECUTEplpgsql 中的命令 https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN.
您可以将其包装到一个函数中。天真的方法:
CREATE OR REPLACE FUNCTION f_unescape(text, OUT _t text)
LANGUAGE plpgsql STABLE AS
$func$
BEGIN
EXECUTE 'SELECT E''' || $1 || ''''
INTO _t;
END
$func$;
Call:
SELECT f_unescape('\r\nabcdef\t0123\x123\n');
这个简单的函数是容易受到单引号的影响在原始字符串中,需要转义。但这有点棘手。在 Posix 转义字符串语法中,单引号可以通过两种方式转义:\'
or ''
。但我们也可以有\\'
等。 基础知识:
- 在 PostgreSQL 中插入带单引号的文本 https://stackoverflow.com/questions/12316953/insert-varchar-with-single-quotes-in-postgresql/12320729#12320729
We could将字符串括在美元引号中,但这不适用于 Posix 转义字符串语法。E'\''
不能用 替换E$$\'$$
罢工>。我们可以添加SET standard_conforming_strings = off
到函数中,那么我们就不必在字符串前面加上E
。但这会禁用函数内联和解释函数体内各处都进行转义。
相反,逃避一切'
和所有(可选)领先\
with regexp_replace()
:
regexp_replace($1, '(\\*)(\''+)', '\1\1\2\2', 'g')
(\\*)
.. 0 个或多个前导\
(\''+)
..捕获 1 个或多个'
'\1\1\2\2'
..每场比赛加倍
'g'
..替换所有出现的情况,而不仅仅是第一个
安全功能
CREATE OR REPLACE FUNCTION f_unescape(IN text, OUT _t text)
RETURNS text
LANGUAGE plpgsql STABLE AS
$func$
BEGIN
EXECUTE $$SELECT E'$$ || regexp_replace($1, '(\\*)(\''+)', '\1\1\2\2', 'g') || $$'$$
INTO _t;
END
$func$;
操作无法逆转可靠的。无法判断哪个特殊字符之前被转义,哪个没有。你可以逃避一切,也可以逃避一切。或者像以前一样手动进行。但是,如果同一个字符包含在原义形式和转义形式中,您就无法再区分它们。
测试用例:
SELECT t, f_unescape(t)
FROM (
VALUES
($$'$$)
, ($$''$$)
, ($$'''$$)
, ($$\'$$)
, ($$\\'$$)
, ($$\\\'$$)
, ($$\\\'''$$)
, ($$\r\\'nabcdef\\\t0123\x123\\\\\'''\n$$)
) v(t);