Bre*_*ham 6 sql database postgresql plpgsql special-characters
我正在尝试编写一个混淆/审查/编辑文本的PLPGSQL函数.
-- Obfuscate a body of text by replacing lowercase letters and numbers with # symbols.
CREATE OR REPLACE FUNCTION obfuscate(str text) RETURNS text AS $$
BEGIN
str := replace(str, '\r', E'\r');
str := replace(str, '\n', E'\n');
str := translate(str, 'abcdefghijklmnopqrstuvwxyz0123456789', rpad('#',36,'#'));
str := replace(str, E'\r', '\r');
str := replace(str, E'\n', '\n');
RETURN str;
END
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
这有效,但请注意舞蹈将转义的换行符和回车转换为各自的字节,然后再返回.这是因为我的数据集包含已被转义的字符串(已被序列化为JSON/YAML的数据),我不想破坏这些值.
还有另一种更方便的方法来取消字符串吗?处理其他转义值也很棒,比如unicode转义序列.
要“转义”字符串,您必须“执行”它 - 从字面上看。使用EXECUTEplpgsql 中的命令。
您可以将其包装到一个函数中。天真的方法:
CREATE OR REPLACE FUNCTION f_unescape(text, OUT _t text)
LANGUAGE plpgsql STABLE AS
$func$
BEGIN
EXECUTE 'SELECT E''' || $1 || ''''
INTO _t;
END
$func$;
Run Code Online (Sandbox Code Playgroud)
称呼:
SELECT f_unescape('\r\nabcdef\t0123\x123\n');
Run Code Online (Sandbox Code Playgroud)
这个简单的函数很容易受到原始字符串中单引号的影响,需要对其进行转义。但这有点棘手。在 Posix 转义字符串语法中,单引号可以通过两种方式转义:\'或''。但我们也可以有\\'等等。基础知识:
我们可以用美元引号将字符串括起来,但这对于 Posix 转义字符串语法不起作用。E'\''不能替换为. 我们可以添加E$$\'$$SET standard_conforming_strings = off到该函数中,然后就不必在字符串前面添加E. 但这会禁用函数内联并解释函数体内各处的转义。
相反,转义所有'和所有(可选)开头\的regexp_replace():
regexp_replace($1, '(\\*)(\''+)', '\1\1\2\2', 'g')
Run Code Online (Sandbox Code Playgroud)
(\\*).. 0 个或更多领先\
(\''+).. 捕获 1 个或更多'
'\1\1\2\2'.. 每场比赛加倍
'g'.. 替换所有出现的情况,而不仅仅是第一个
SELECT f_unescape('\r\nabcdef\t0123\x123\n');
Run Code Online (Sandbox Code Playgroud)
操作不能可靠地反转。无法判断哪个特殊字符之前被转义,哪个没有。你可以逃避一切,也可以逃避一切。或者像以前一样手动进行。但是,如果同一个字符包含在原义形式和转义形式中,您就无法再区分它们。
测试用例:
regexp_replace($1, '(\\*)(\''+)', '\1\1\2\2', 'g')
Run Code Online (Sandbox Code Playgroud)