字符串分割問題詳解

字符串分割問題詳解

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(關於字符集的最基本知識)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章