Erlang的UTF-8字符串解析函数

分享ErlangUTF-8 by 达达 at 2011-01-13

游戏的聊天部分需要用到关键字过滤,客户端传上来的字符串是UTF8格式,于是写了下面这组UTF8字符解析的函数。这里省去不用unicode模块的个中缘由和具体替换算法的描述一千字,实在懒得说那么多废话,呵呵。

引用一段网上摘抄的UTF8编码规则描述:

UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;
如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。

如表:
<80 1字节 0xxxxxxx
<E0 2字节 110xxxxx 10xxxxxx
<F0 3字节 1110xxxx 10xxxxxx 10xxxxxx
<F8 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
<FC 5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
<FE 6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

有了上面这么详细的描述,写代码实在没什么技术含量了,呵呵。

get_utf8_char ([]) ->
    {0, []};
get_utf8_char ([Char1 | String]) ->
    get_utf8_char(Char1, String).

get_utf8_char (Char1, String) when Char1 < 16#80 ->
    {Char1, String};
get_utf8_char (Char1, String) when Char1 < 16#E0 ->
    [Char2 | String2] = String,
    {{Char1, Char2}, String2};
get_utf8_char (Char1, String) when Char1 < 16#F0 ->
    [Char2, Char3 | String2] = String,
    {{Char1, Char2, Char3}, String2};
get_utf8_char (Char1, String) when Char1 < 16#F8 ->
    [Char2, Char3, Char4 | String2] = String,
    {{Char1, Char2, Char3, Char4}, String2};
get_utf8_char (Char1, String) when Char1 < 16#FC->
    [Char2, Char3, Char4, Char5 | String2] = String,
    {{Char1, Char2, Char3, Char4, Char5}, String2};
get_utf8_char (Char1, String) when Char1 < 16#FE->
    [Char2, Char3, Char4, Char5, Char6 | String2] = String,
    {{Char1, Char2, Char3, Char4, Char5, Char6}, String2}.

返回格式说明:

{utf8_char_bytes, trim_string}

utf8_char_bytes  -- utf8字符对应的字节,可能返回1-6个字节,当大于1个字节时,这个值是一个元组。
trim_strimg -- 字符串的剩余部分