PostgreSQL , 全角 , 半角 , 转换 , ascii , chr , 编码
http://blog.qdac.cc/?p=1289
我们知道,客户许多时候录入数据时,并不注意输入法是否是全角模式,然后就造成输入的内容,有的是全角有的是半角,造成我们做分析统计时的不便,为此,编写相应的函数。当然这个过程应尽量在前台完成,但如果针对已经存在的数据,下面提供的两个函数就比较方便了。
1、全角转换为半角函数
--© 2014,swish,原版首发:http://blog.qdac.cc/?p=1281,自由使用,保留版权
create or replace function CnFullToHalf(s character varying)
returns character varying
as
$$
declare
retval character varying;
c character varying;
l integer;
begin
l=length(s);
retval='';
while l>0 loop
c=left(s,1);
if c=' ' then -- 全角空格
retval=retval||' ';
elsif c>='!' and c<='~' then -- 全角!到~的范围
retval=retval || chr(ascii('!')+ascii(c)-ascii('!'));
else
retval=retval||c;
end if;
s=substring(s,2,l-1);
l=l-1;
end loop;
return retval;
end;
$$language plpgsql strict immutable;
2、半角转全角
--© 2014,swish,原版首发:http://blog.qdac.cc/?p=1281,自由使用,保留版权
create or replace function CnHalfToFull(s character varying)
returns character varying
as
$$
declare
retval character varying;
c integer;
l integer;
begin
l=length(s);
retval='';
while l>0 loop
c=ascii(left(s,1));
if c=32 then -- 空格
retval=retval||' ';
elsif c>=33 and c<=126 then
retval=retval || chr(ascii('!')+c-ascii('!'));
else
retval=retval||chr(c);
end if;
s=substring(s,2,l-1);
l=l-1;
end loop;
return retval;
end;
$$language plpgsql strict immutable;
适合UTF8字符集。
例子
test01=# select CnHalfToFull('123ab?-_.*&^%#@~+_=-:;/><|\\"y');
cnhalftofull
--------------------------------------------------------------
123ab?-_.*&^%#@~+_=-:;/><|\\"y
(1 row)
test01=# select CnFullToHalf('123ab?-_.*&^%#@~+_=-:;/><|\\"y');
cnfulltohalf
--------------------------------
123ab?-_.*&^%#@~+_=-:;/><|\\"y
(1 row)
全角字符unicode编码从65281~65374 (十六进制 0xFF01 ~ 0xFF5E)
半角字符unicode编码从33126 (十六进制 0x21 0x7E)
空格比较特殊,全角为 12288(0x3000),半角为 32(0x20)
除空格外,全角/半角按unicode编码排序在顺序上是对应的(半角 + 65248 = 全角)
所以可以直接通过用+-法来处理非空格数据,对空格单独处理。
chr()函数用一个范围在range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
unichr()跟它一样,只不过返回的是Unicode字符。
ord()函数是chr()函数或unichr()函数的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的ASCII数值,或者Unicode数值。
根据以上规则,可以写成全角半角转换函数
create or replace function full_to_half(text) returns text as
$$
select string_agg(col, '') from
( select
case when ascii(col) >= 65281 and ascii(col) <=65374 then chr(ascii(col)-65248)
when ascii(col) = 12288 then chr(32)
else col
end AS col
from (select regexp_split_to_table($1, '') as col) t
) tt;
$$ language sql strict immutable;
create or replace function half_to_full(text) returns text as
$$
select string_agg(col, '') from
( select
case when ascii(col) >= 33 and ascii(col) <=126 then chr(ascii(col)+65248)
when ascii(col) = 32 then chr(12288)
else col
end AS col
from (select regexp_split_to_table($1, '') as col) t
) tt;
$$ language sql strict immutable;
test01=# select full_to_half('123ab?-_.*&^%#@~+_=-:;/><|\\"y!');
full_to_half
---------------------------------
123ab?-_.*&^%#@~+_=-:;/><|\\"y!
(1 row)
test01=# select half_to_full('123ab?-_.*&^%#@~+_=-:;/><|\\"y! 123ab?-_.*&^%#@~+_=-:;/><|\\"y!');
half_to_full
------------------------------------------------------------------------------------------------------------------------------------
123ab?-_.*&^%#@~+_=-:;/><|\\"y! 123ab?-_.*&^%#@~+_=-:;/><|\\"y!
(1 row)
http://blog.qdac.cc/?p=1289
https://www.biaodianfu.com/python-convert-between-unicode-fullwidth-halfwidth-characters.html