字符串分割問題詳解
DionysosLai 20150817
前段時間,有個需求,要求對一串字符串進行單個字符分割。比如“今天是情人節!”,分割結果是“今”、“天”、“是”、“是”、“情”、“人”、“節”、“!”。由於字符串中,包含了中英文,特殊字符等,而每個字符並不是統一字節編碼,比方說英文是單個字節編碼,中文是二個字節編碼了。因此,有必要判斷是那種編碼方式。
在處理這個問題前,有必要先了解下字符編碼的一些基本知識,瞭解ASCII,Unicode,UTF-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表示阿拉伯字母Ain,U+0041表示英語的大寫字母A,U+4E25表示漢字"嚴"
但是到目前這裏,Unicdoe只是規定了編碼方式,並沒有規定存儲方式。因此,存在了兩個問題。1. 如何區分Unicode和ASCII?比如“嚴”使用兩個2字節編碼,那麼計算機如何辨識這兩個字節是表示一個符號,還是兩個符號。2.存儲問題,如果Unicode規定使用3個字節表示一個符號,那麼對於英語字母,前面2個字節必定全爲0,這樣就造成了非必要的浪費。
UTF-8,便是Unicode的實現方式之一,相應的實現方式還設有UTF-16、UTF-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-16、UTF-32,那麼請自行Google,原理差不多。
延伸閱讀
* http://www.joelonsoftware.com/articles/Unicode.html(關於字符集的最基本知識)