4

plpgsqlを使用せずに、pgsqlSELECTステートメント内の特定のテキストをurlencodeしようとしています。

このアプローチの問題:

select regexp_replace('héllo there','([^A-Za-z0-9])','%' || encode(E'\\1','hex'),'g')

...実際に機能する置換式内から関数を呼び出す別の方法がない限り、encode関数にはregexpパラメーターが渡されません。したがって、それ自体で一致を16進値にエンコードできる置換式があるかどうか疑問に思います。

機能の他の組み合わせがあるかもしれません。そこには賢い正規表現があるだろうと思っていましたが(それでも答えかもしれません)、それを見つけるのに苦労しています。

4

4 に答える 4

7
select regexp_replace(encode('héllo there','hex'),'(..)',E'%\\1','g');

ただし、これにより、英数字が人間が判読できる状態にはなりません。

于 2008-12-04T16:38:30.567 に答える
1

これはかなり短いバージョンで、plpgsql ではなく「純粋な SQL」関数です。マルチバイト文字 (3 バイトおよび 4 バイトの絵文字を含む) がサポートされています。

create or replace function urlencode(in_str text, OUT _result text) returns text as $$
  select
    string_agg(
      case
        when ol>1 or ch !~ '[0-9a-za-z:/@._?#-]+' 
          then regexp_replace(upper(substring(ch::bytea::text, 3)), '(..)', E'%\\1', 'g')
        else ch
      end,
      ''
    )
  from (
    select ch, octet_length(ch) as ol
    from regexp_split_to_table($1, '') as ch
  ) as s;
$$ language sql immutable strict;
于 2016-10-19T02:29:27.733 に答える
1

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$
于 2015-11-09T19:08:11.960 に答える
-3

CLRを使用して名前空間をインポートするか、このリンクに示されている関数を使用できます。これにより、エンコードを行うT-SQL関数が作成されます。

http://www.sqljunkies.com/WebLog/peter_debetta/archive/2007/03/09/28987.aspx

于 2008-12-08T13:29:16.327 に答える