码迷,mamicode.com
首页 > 其他好文 > 详细

字符串分割问题详解

时间:2015-08-19 20:36:10      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:lua   编码   utf-8   unicode   

字符串分割问题详解

DionysosLai 20150817

        前段时间,有个需求,要求对一串字符串进行单个字符分割。比如“今天是情人节!”,分割结果是“今”、“天”、“是”、“是”、“情”、“人”、“节”、“!”。由于字符串中,包含了中英文,特殊字符等,而每个字符并不是统一字节编码,比方说英文是单个字节编码,中文是二个字节编码了。因此,有必要判断是那种编码方式。

        在处理这个问题前,有必要先了解下字符编码的一些基本知识,了解ASCIIUnicodeUTF-8等之间的关系,这里简要说明一下,具体文章:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html,讲个非常清楚了。

        ASCII编码,这是最早的字符编码方式,长度为一个字节,00000000~11111111,可以表示256个字符。由于60年代美国制定时,不考虑其他语种,因此只占用了128个字符,所以字符编码的第一位均为0

        ASCII编码,由于其他语种存在了一些不同字母,因此从128~255进行了重新编码。但是,由于各个国家的字符时不统一的,因此这剩余的128个字符,并不是很够用,这就造成了不同国家,有各个不同编码方式,当然从0~128的字符是一样的。

        Unicode,由于各个国家不同编码方式,造成了通讯上的方面。因此需要出现一种同一个的编码方式,给予每个符号都有统一的一种编码方式。Unicode就是这样诞生的,比如U+0639表示阿拉伯字母AinU+0041表示英语的大写字母AU+4E25表示汉字""

        但是到目前这里,Unicdoe只是规定了编码方式,并没有规定存储方式。因此,存在了两个问题。1. 如何区分UnicodeASCII?比如“严”使用两个2字节编码,那么计算机如何辨识这两个字节是表示一个符号,还是两个符号。2.存储问题,如果Unicode规定使用3个字节表示一个符号,那么对于英语字母,前面2个字节必定全为0,这样就造成了非必要的浪费。

        UTF-8,便是Unicode的实现方式之一,相应的实现方式还设有UTF-16UTF-32等。UTF-8是一种变长的编码方式,使用1~4个字节表示一个符号。UTF-8的编码规则有2条:注意:我们解决字符串的分割原理,便是从这里得到的)

        1. 对于单字节的符号,字节的第一位设为0,后面7为这个符号的unicode编码。因此,对于英语字符,UTF-8编码和ASCII编码一致,其第一个字节大小0~127(本身编码就是使用一个字节表示);

        2. 对于n个字节的符号(n > 1)第一个字节的前n为设为1(重点)n+1为设为0后面字节的前2为一律设为10。剩余的二进制位,全部为这个符号的Unicode码。

比方2个字节编码的,其UTF-8编码方式为110xxxxx,10xxxxxx。第一个字节大小为192~223。依次可以类推3个字节编码。

 

        根据这个可以列出下表:

        1个字节编码:第一个字节大小 0~127

        2个字节编码:第一个字节大小 192~223

        3个字节编码:第一个字节大小 224~239

        4个字节编码:第一个字节大小 240~247

 

        因此,代码如下:(ps,最近使用lua开发游戏,就用lua写了):

function stringCut(str)
    local strCut = {};
 
    local cutIndex = 1;
    while true do
        if cutIndex > string.len(str) then
            break;
        end
        local curByte = string.byte(str, cutIndex) 
        local byteCount = 1;
        if curByte>=0 and curByte<=127 then          -- 1个字节编码
            byteCount = 1;
        elseif curByte>=192 and curByte<=223 then    -- 2个字节编码
            byteCount = 2;  
        elseif curByte>=224 and curByte<=239 then    -- 3个字节编码
            byteCount = 3;
        elseif curByte>=240 and curByte<=247 then   -- 4个字节编码
            byteCount = 4;
        end
        local value = string.sub(str, cutIndex, cutIndex+byteCount-1);
        table.insert(strCut, value);
        cutIndex = cutIndex + byteCount;
    end
 
    return strCut;
end


        注意,这里的编码方式是UTF-8,如果编码方式是UTF-16UTF-32,那么请自行Google,原理差不多。

        延伸阅读

        * http://www.joelonsoftware.com/articles/Unicode.html(关于字符集的最基本知识)

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

字符串分割问题详解

标签:lua   编码   utf-8   unicode   

原文地址:http://blog.csdn.net/dionysos_lai/article/details/47784561

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!