2016-05-04 7 views
3

にそのchar型の値に文字列内のすべての六角を変換します文字列内のすべての16進数をchar値に変換します。私が考えることができる唯一の方法は、正規表現関数を使用することです。私は2つの異なる方法でそれを試み、両方のためのエラーメッセージを受け取った:私はこのような文字列を変換しようとしている、赤方偏移では赤方偏移

SELECT REGEXP_REPLACE(hex_string, '%([[:xdigit:]][[:xdigit:]])', CHR(x'\\1'::int)) 
ERROR: 22P02: "\" is not a valid hexadecimal digit 

SELECT REGEXP_REPLACE(hex_string, '%([[:xdigit:]][[:xdigit:]])',CHR(STRTOL('0x'||'\\1', 16)::int)) 
ERROR: 22023: The input 0x\1 is not valid to be converted to base 16 

CHRとSTRTOL機能は単独で機能します。例えば:私は(CHR及びstrtolは除く)は、異なる関数を使用して同じパターンを実行する場合

SELECT CHR(x'3A'::int) 
SELECT CHR(STRTOL('0x3A', 16)::int) 

両方戻り

: 

そして、それが動作:

REGEXP_REPLACE(hex_string, '%([[:xdigit:]][[:xdigit:]])', LOWER('{H}'||'\\1'||'{/H}')) 

戻る

http{h}3A{/h}{h}2F{/h}{h}2F{/h}www.amazon.com{h}2F{/h}Test{h}3F{/h}name{h}3D{/h}Gary{h}26{/h}Bob 

しかし、なんらかの理由でそれらの関数は正規表現マッチンググループを認識しません。

どのようにすればいいですか?

他の解決策は、すべての特殊な16進文字にネストされたREPLACE()関数を使用することですが、これはおそらく最後の手段です。

答えて

3

あなたがしたいことを「URLデコード」といいます。

は現在、これを行うための組み込み関数が存在しませんが、カスタムUser-Defined Function(あなたがprivilegesを必要としていることを確認してください)を作成することができます

CREATE FUNCTION urldecode(url VARCHAR) 
RETURNS varchar 
IMMUTABLE AS $$ 
    import urllib 
    return urllib.unquote(url).decode('utf8') # or 'latin-1', depending on how the text is encoded 
$$ LANGUAGE plpythonu; 

例をクエリ:

SELECT urldecode('http%3A%2F%2Fwww.amazon.com%2FTest%3Fname%3DGary%26Bob'); 

結果:

http://www.amazon.com/Test?name=Gary&Bob 
+0

これはうまくいきました。 ちょっと参考に、長い文字列で実行するとこのエラーメッセージが表示されます。エラー:XX000:文字タイプが長すぎます。 最大varchar(65535)を使用するように関数を変更したところ、完全に機能しました。 –

+0

私のデータのいくつかがこのエラーを投げました: UnicodeDecodeError: 'utf8'コーデックは位置4468のバイト0xecをデコードできません:無効な継続バイトです。私はutf8の代わりに私のエンコーディングをlatin-1に変更して解決しました。 –

+0

@NghiLe:更新いただきありがとうございます。私はこれを答えに加えました。 – hiddenbit

関連する問題