由於當前的ruby並不支援unicode, 所以中文相關的處理在ruby中一直比較模糊,基本上是各自嘗試的路子, 我也列出一些協助自己整理思路
utf8和unicode的關係
utf其實是(Unicode Translation Format), 也就是unicode在傳輸時候的編碼, 有utf8和utf16等多種編碼, 其實uf8是一個對中文字很不友好的編碼, 為什麼呢,因為在utf8中, 一個中文是佔用3個位元組,而一個英文ascii字元卻只佔用1個位元組, 這樣一方面使得中文體積膨脹較厲害, 另外一方面也不能簡單的通過計算位元組數來推算字元數. utf16就比較正常, 每個字元佔用兩個位元組.但是目前utf16已經後面的utf32應用較少, utf8 是比較公認的編碼
utf8 還是 gb2312/gbk
我個人選擇utf8,因為我覺得gb2312/gbk不是通用編碼,如果使用可能還會有其他問題(比如多語言支援)
轉換編碼
我們需要require 'iconv' 庫, 然後執行
Iconv.conv("utf8","GBK","....") #把字元由GBK轉換為UTF8
當源字元集中含有非法編碼的時候,我們需要告訴iconv忽略, 否則iconv會報錯停止
Iconv.conv("utf8//IGNORE","GBK//IGNORE","....")
utf8 的中文操作:
計算字元數:
在預設的ruby環境下面, 需要執行
require 'jcode'
$KCODE='u' # 或者$KCODE='UTF8' 兩者是等價的
計算字元數:
使用jsize或者jlength
"你好".size # 6
"你好".jsize # 2
截取字元操作
"你好"[0,1] #亂碼
"你好".scan(/./)[0,1].join # "你"
當然還有另外一個辦法:
利用utf16編碼每個字都是2個位元組(頭還有兩個位元組)的特點,我們可以先把字元轉換為utf16,然後按照[0,n*2+2]的方法截取前n個字元 (實驗成功.求證中)
Iconv.conv("UTF8","UTF16",Iconv.conv("UTF16","UTF8","你好a中b文")[0,8]) #你好a