URL の可読性を維持しながら、組み込み関数を使用してエンコードを処理する、私が作成した関数を次に示します。
(オプションの) 安全な文字と (最大 1 つの) 安全でない文字のペアをキャプチャする正規表現の一致。ネストされた選択により、これらのペアをエンコードして再結合し、完全にエンコードされた文字列を返すことができます。
私はあらゆる種類の順列(先頭/末尾/のみ/繰り返しエンコードされた文字)を使用してテストスイートを実行しましたが、これまでのところ正しくエンコードされているようです.
安全な特殊文字は _ ~ です。- と /。そのリストに「/」を含めることはおそらく非標準ですが、入力テキストがパスである可能性があり、それを残したいというユースケースに適合します。
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$