Javascript encodeURI喜欢postgresql中的函数吗?

Rok*_*oki 5 postgresql stored-procedures urlencode plpgsql

PostgreSQL/plpgsql中有没有与javascripts encodeURI相同的函数/存储过程?

这是什么意思?Javascript有一个方便的内置函数来编码任何类型的URL:

encodeURI(url) - >返回已编码的url

例如: encodeURI('http://hu.wikipedia.org/wiki/São_Paulo')- >返回一个String"http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo"

我寻找完全一样的.

我不想单独编码每个参数.我不希望像javascript encodeURIComponent这样的函数不一样.上面的例子产生了不同的输出

encodeURIComponent('http://hu.wikipedia.org/wiki/São_Paulo')
Run Code Online (Sandbox Code Playgroud)

- > "http%3A%2F%2Fhu.wikipedia.org%2Fwiki%2FS%C3%A3o_Paulo"

它编码整个字符串而不仅仅是路径部分.所以这不是我想要的.我需要一个plpgsql函数,它导致javascript函数encodeURI的等效输出.

谢谢!

vye*_*rov 13

慢和低效,考虑做C这个功能的版本:

CREATE OR REPLACE FUNCTION urlencode(in_str text, OUT _result text)
    STRICT IMMUTABLE AS $urlencode$
DECLARE
    _i      int4;
    _temp   varchar;
    _ascii  int4;
BEGIN
    _result = '';
    FOR _i IN 1 .. length(in_str) LOOP
        _temp := substr(in_str, _i, 1);
        IF _temp ~ '[0-9a-zA-Z:/@._?#-]+' THEN
            _result := _result || _temp;
        ELSE
            _ascii := ascii(_temp);
            IF _ascii > x'07ff'::int4 THEN
                RAISE EXCEPTION 'Won''t deal with 3 (or more) byte sequences.';
            END IF;
            IF _ascii <= x'07f'::int4 THEN
                _temp := '%'||to_hex(_ascii);
            ELSE
                _temp := '%'||to_hex((_ascii & x'03f'::int4)+x'80'::int4);
                _ascii := _ascii >> 6;
                _temp := '%'||to_hex((_ascii & x'01f'::int4)+x'c0'::int4)
                            ||_temp;
            END IF;
            _result := _result || upper(_temp);
        END IF;
    END LOOP;
    RETURN ;
END;
$urlencode$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

结果:

# select urlencode('http://hu.wikipedia.org/wiki/São_Paulo');
-[ RECORD 1 ]------------------------------------------
urlencode | http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo
Run Code Online (Sandbox Code Playgroud)


The*_*lal 7

这是一个非常古老的线程,但令人惊讶的是,之前发布的解决方案似乎都不符合相关的RFC 3986。所以这里有两个 PostgreSQL 函数encode_uri(如果你想编码一个完整的URI)和encode_uri_component(如果你只想编码URI的一个组成部分,例如查询参数的键或值),它们结合了Nick的错误解决方案ElDiabolo的注释,以及Kev 从相关线程 到单个有效的仅 SQL 解决方案的部分解决方案。

工作原理:首先,将字符串分解为单个字符,然后对每个多字节字符和每个不允许的字符进行十六进制编码。

编码 URI 组件:

create or replace function encode_uri_component(text) returns text as $$
    select string_agg(
        case
            when bytes > 1 or c !~ '[0-9a-zA-Z_.!~*''()-]+' then 
                regexp_replace(encode(convert_to(c, 'utf-8')::bytea, 'hex'), '(..)', E'%\\1', 'g')
            else 
                c
        end,
        ''
    )
    from (
        select c, octet_length(c) bytes
        from regexp_split_to_table($1, '') c
    ) q;
$$ language sql immutable strict;
Run Code Online (Sandbox Code Playgroud)

编码完整 URI:

create or replace function encode_uri(text) returns text as $$
    select string_agg(
        case
            when bytes > 1 or c !~ '[0-9a-zA-Z_.!~*''();,/?:@&=+$#-]+' then 
                regexp_replace(encode(convert_to(c, 'utf-8')::bytea, 'hex'), '(..)', E'%\\1', 'g')
            else 
                c
        end,
        ''
    )
    from (
        select c, octet_length(c) bytes
        from regexp_split_to_table($1, '') c
    ) q;
$$ language sql immutable strict;
Run Code Online (Sandbox Code Playgroud)


Nei*_*gan 6

用PL/V8 ......作弊?

create function encode_uri(text) returns text language plv8 strict immutable as $$
  return encodeURI($1);
$$;
Run Code Online (Sandbox Code Playgroud)


tso*_*ohr 6

今天我遇到了“不会处理 3 个(或更多)字节序列”。对于韩语字符,虽然我已经使用@vyegorov的答案很长一段时间了,一年多了,需要更改它只是转储带有“%”前缀的bytea十六进制字符串。

\n\n
CREATE OR REPLACE FUNCTION urlencode(in_str text, OUT _result text)\n    STRICT IMMUTABLE AS $urlencode$\nDECLARE\n    _i      int4;\n    _temp   varchar;\n    _hex    varchar;\n    _ascii  int4;\nBEGIN\n    _result = \'\';\n    FOR _i IN 1 .. length(in_str) LOOP\n        _temp := substr(in_str, _i, 1);\n        IF _temp ~ \'[0-9a-zA-Z:/@._?#-]+\' THEN\n            _result := _result || _temp;\n        ELSE\n            _hex := encode(_temp::bytea, \'hex\');\n            _temp := \'\';\n            WHILE LENGTH(_hex) > 0 LOOP\n                _temp := _temp || \'%\' || SUBSTRING(_hex, 1, 2);\n                _hex := SUBSTRING(_hex, 3, 999);\n            END LOOP;\n            _result := _result || upper(_temp);\n        END IF;\n    END LOOP;\n    RETURN ;\nEND;\n$urlencode$ LANGUAGE plpgsql;\n
Run Code Online (Sandbox Code Playgroud)\n\n

例子,

\n\n
SELECT urlencode(\'a\') UNION ALL  --> "a"\nSELECT urlencode(\'\xc3\x80\') UNION ALL  --> "%C3%80"\nSELECT urlencode(\'\xc4\x80\') UNION ALL  --> "%C4%80"\nSELECT urlencode(\'\xc9\x99\') UNION ALL  --> "%C9%99"\nSELECT urlencode(\'\xce\xb1\') UNION ALL  --> "%CE%B1"\nSELECT urlencode(\'\xea\xb0\x80\') UNION ALL --> "%EA%B0%80"\nSELECT urlencode(\'\xe4\xb8\x8a\') UNION ALL --> "%E4%B8%8A"\nSELECT urlencode(\'\xe3\x81\x84\')           --> "%E3%81%84"\n
Run Code Online (Sandbox Code Playgroud)\n


Pav*_*ule 5

我写了解决这个问题的PostgreSQL 扩展url_enocode

postgres=# select url_encode('http://hu.wikipedia.org/wiki/São_Paulo');
                      url_encode                       
???????????????????????????????????????????????????????
http%3A%2F%2Fhu.wikipedia.org%2Fwiki%2FS%C3%A3o_Paulo
Run Code Online (Sandbox Code Playgroud)

或者

postgres=# select uri_encode('http://hu.wikipedia.org/wiki/São_Paulo');
               uri_encode                  
---------------------------------------------
http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo
Run Code Online (Sandbox Code Playgroud)