天天看点

PostgreSQL 中如何找出记录中是否包含编码范围内的字符,例如是否包含中文

postgresql , 是否含有中文

从已有字符串内容中找出含有中文,或者找出含有单字节字符的记录。

方法要从字符串在数据库中的编码和存储说起。比如多字节字符集,单字节字符sql_ascii。

比如postgresql中utf8, euc_cn属于多字节字符集,编码为变长编码。

sql_ascii为无编码字符集,存储为字节流。

要从不同字符集中找出含有中文的记录,该怎么找?

已有数据库如下,注意编码

在postgres, db, db1中分别创建测试数据如下

参考如下文档

<a href="http://www.iteye.com/topic/977671">http://www.iteye.com/topic/977671</a>

本次研究的unicode对象是unicode 5.2.0版本。现在最新的是6.0版

对于这次研究的unicode把编码分为以下几个平面(英文中是plane,可以认为就是不同的区位)

unicode可以逻辑分为17平面(plane),每个平面拥有65536( = 216)个代码点,虽然目前只有少数平面被使用。

平面0 (0000–ffff): 基本多文种平面(basic multilingual plane, bmp).

平面1 (10000–1ffff): 多文种补充平面(supplementary multilingual plane, smp).

平面2 (20000–2ffff): 表意文字补充平面(supplementary ideographic plane, sip).

平面3 (30000–3ffff): 表意文字第三平面(tertiary ideographic plane, tip).

平面4 to 13 (40000–dffff)尚未使用

平面14 (e0000–effff): 特别用途补充平面(supplementary special-purpose plane, ssp)

平面15 (f0000–fffff)保留作为私人使用区(private use area, pua)

平面16 (100000–10ffff),保留作为私人使用区(private use area, pua)

最有用的当然就是bmp平面0了编码从u+0000至u+ffff。那里包含了几乎全部的常用字符。

unicode基本平面区的编码区间含义

为鉴于unicode原有的16位空间不足以应用,于是从unicode 3.1版本开始,设立了16个扩展字码空间,称为辅助平面,

使 unicode 的可使用空间由6万多字增至约100万字。辅助平面字符要用上4字节来存储。

unicode中的几大区间

最后小结下:

1. 现在网上大多数用于判断中文字符的是 u+4e00..u+9fa5 这个范围是只是“中日韩统一表意文字”这个区间,但这不是全部,如果要全部包含,则还要他们的扩展集、部首、象形字、注间字母等等;

2e80-a4cf 加上 f900-faff 加上 fe30-fe4f

其中 

2e80-a4cf 

包含了中日朝部首补充、康熙部首、表意文字描述符、中日朝符号和标点、日文平假名、日文片假名、注音字母、谚文兼容字母、象形字注释标志、注音字母扩展、中日朝笔画、日文片假名语音扩展、带圈中日朝字母和月份、中日朝兼容、中日朝统一表意文字扩展a、易经六十四卦符号、中日韩统一表意文字、彝文音节、彝文字根

f900-faff

中日朝兼容表意文字

fe30-fe4f

中日朝兼容形式

所以,一般用4e00-9fa5已经可以,如果要更广,则用2e80-a4cf || f900-faff || fe30-fe4f

2. 全角ascii、全角中英文标点、半宽片假名、半宽平假名、半宽韩文字母:ff00-ffef

3. 不要太关心简繁中文的区别,如果要明确非要简体中文可参考unicode中简体中文编码

参考

<a href="http://tools.jb51.net/table/gb2312">http://tools.jb51.net/table/gb2312</a>

gb2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;同时,gb 2312收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。整个字符集分成94个区,每区有94个位。

gb2312,又称为gb0,由中国国家标准总局发布,1981年5月1日实施

gb2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个

gb2312是一种区位码。分为94个区(01-94),每区94个字符(01-94)

01-09区为特殊符号

10-15区没有编码

16-55区为一级汉字,按拼音排序,共3755个

56-87区为二级汉字,按部首/笔画排序,共3008个

88-94区没有编码

gb2312只是编码表,在计算机中通常都是用"euc-cn"表示法,即在每个区位加上0xa0来表示。区和位分别占用一个字节。

中文从啊到齄 编码区间是b0a1-f7ff

1. 数据库为utf8编码

2e80-a4cf 加上 f900-faff 加上 fe30-fe4f

2. 数据库为euc_cn编码

3. 数据库为sql_ascii编码

由于sql_ascii不检查编码,存入的数据完全取决于客户端编码,所以这种方法有一定的漏洞。

比如

由于我的客户端为utf8编码,存入的就是utf8编码的值,这样查是可以的。

使用转换函数,或者长度判断即可。

1. sql_ascii编码

sql_ascii编码,以字节流形式存储,所以字节长度字符长度一样。

所以只能使用正则如下,找到包含非ascii的记录

2. 多字节编码

多字节编码的数据库,使用字节长度和字符长度比较,不一样,说明包含非单字节字符。

或者使用正则