字符串分割问题详解

字符串分割问题详解

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(关于字符集的最基本知识)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值