这是我编写的一个函数,它使用内置函数处理编码,同时保留 URL 的可读性。  
正则表达式匹配以捕获(可选)安全字符和(最多一个)非安全字符对。嵌套选择允许对这些对进行编码和重新组合,返回一个完全编码的字符串。
我已经运行了一个具有各种排列的测试套件(前导/尾随/仅/重复的编码字符,到目前为止它似乎编码正确。
安全的特殊字符是 _ ~ 。- 和 /。我在该列表中包含“/”可能是非标准的,但适合我的用例,其中输入文本可能是路径并且我希望保留它。
CREATE OR REPLACE FUNCTION oseberg.encode_uri(input text)
  RETURNS text
  LANGUAGE plpgsql
  IMMUTABLE STRICT
AS $function$
DECLARE
  parsed text;
  safePattern text;
BEGIN
  safePattern = 'a-zA-Z0-9_~/\-\.';
  IF input ~ ('[^' || safePattern || ']') THEN
    SELECT STRING_AGG(fragment, '')
    INTO parsed
    FROM (
      SELECT prefix || encoded AS fragment
      FROM (
        SELECT COALESCE(match[1], '') AS prefix,
               COALESCE('%' || encode(match[2]::bytea, 'hex'), '') AS encoded
        FROM (
          SELECT regexp_matches(
            input,
            '([' || safePattern || ']*)([^' || safePattern || '])?',
            'g') AS match
        ) matches
      ) parsed
    ) fragments;
    RETURN parsed;
  ELSE
    RETURN input;
  END IF;
END;
$function$