湘里妹子学术网

 找回密码
 注册
查看: 6459|回复: 5

如何分辦字串是簡體中文, 還是繁體中文,何分辦字串是 GB, Big5, or

[复制链接]
发表于 2005-3-16 13:14:03 | 显示全部楼层 |阅读模式
Alfred

呵~這不是什麼秘密。

先看下表
GBK (GB2312的superset): 1st byte 是 81 - FE,2nd byte 是 40 - FE
GB2312: 1st byte 是 A1 - F7,2nd byte 是 A1 - FE
Big5: 1st byte 是 A1 - F9,2nd byte 是 40 - FE

內地用的GBK通常都是GB2312區域內的簡體字,測試字串時若發現某中文是在GB2312區域之外(或低於總字數的某個百份比,接近0%)可假設字串是Big5,反之則是GBK。不過,這方法若果字串包括GBK繁體字、罕用字、或一些特殊符號時可能失效。

另一方法是取樣某數量最常用的中文字和標點,用GB及Big5各做一個表,
測試字串時對照上述兩個表,比較哪一個表內的字出現率較多。

我用的是上述兩種方法結合。

Unicode純文字文件基本上都有Byte order mark (BOM)
unicode little endian: FF FE
unicode big endian: FE FF
只須讀入文件前端的頭兩個字碼就可以分辨出來。
发表于 2005-3-18 22:59:53 | 显示全部楼层
是否用unicode编码,检测也不是那么容易。
例如,Artvine先生提到的那两种,算是UCS-2的两种实例;此外常见的其实还有UTF-7、UTF-8、UCS-4、GB16030等等编码方式。
 楼主| 发表于 2005-3-20 08:15:39 | 显示全部楼层
討論到編碼問題,藉此另引些問題提供討論與思考。最近的瓶頸是ISO.../Utf-8...的問題。跟美國、俄羅斯的朋友談論程式,儘管他們如何免費、如何能Index多少g、如何作到全文檢索的第三層Highligth(Cache or  LWP)。

但是對CJKV,他們不懂。

能不能作出基本的More then One byte的基本涵數呢?
发表于 2005-3-20 18:53:15 | 显示全部楼层
Artvine 于 2005-3-20 08:15 写道:
...
能不能作出基本的More then One byte的基本涵數呢?
...


不知道Artvine先生具体指的是什么?
是指不依赖操作系统所提供的功能,自写函数实现Unicode的各种编码转换,还是...?

实际工作中,如果以Unicode为枢纽,要用到的函数似乎可以分两大类:
1)Unicode转换函数。例如Unicode的UTF-8、UCS2、UCS4、GB18030、BIG5等之间的相互转换。
2)Unicode操作类函数。例如基于Unicode字符串相加、替换、甚至汉字简体、繁体互相转换等。
 楼主| 发表于 2005-3-23 13:08:16 | 显示全部楼层
utf-8文件可以選選擇是否加Byte Order Mark (BOM),先檢查文件前端有沒有BOM ($EF $BB $BF),有的就是utf-8。
至於沒有BOM的文件,可經測試字符的編排模式去判斷是否utf-8。範例:

CODE  

function isUTF8(s: string): boolean;
var
i: integer;
begin
result := true;
i := 1;
repeat
   if (Ord(s) and $80) = 0 then inc(i) //單字節英文字符
   else
     if ((Ord(s[i+1]) and $E0) = $C0) then //是雙字節組合的首字節
     begin //2-byte code
       if (Ord(s[i+1]) and $C0) = $80 then //第二字節在有效範圍
         i := i + 2
       else  //並非UTF8字串
       begin
         result := false;
         break;
       end;
     end
     else if ((Ord(s) and $F0) = $E0) then //是三字節組合的首字節
     begin
       if ((Ord(s[i+1]) and $C0) = $80) and ((Ord(s[i+2]) and $C0) = $80) then
         i := i + 3  //第二及第三字節皆有效
       else //並非UTF8字串
       begin
         result := false;
         break;
       end;
     end
     else  //並非UTF8字串
     begin
       result := false;
       break;
     end;
   if i > 3000 then break;      //檢查字串首3000字節已足夠
until i >= length(s);
end;

GB/Big5並沒有絶對有效的方法去區分,常用的方法有二。

1. 內地常用的簡體字幾乎都是在GB2312的區域。GB2312字符的首字節是$A1..$F7,次字節是$A1..$FE;而Big5的首字節是$A1..$F9,次字節是$40..$FE。只要檢查字串內的每個字,若所有字的次字節的數值皆大於$A0則為文件應為GB,反是則是Big5。缺點是若果GB字串內有GBK繁體字時會被錯判為Big5,而當Big5字串過短所有字又剛好在GB2312區時會被錯判為GB。不過,這方法的準確率一般會是九成以上。

2. 編修一個GB及Big5的常用字表(包括標點),檢查這些字碼在文章的出現次數,選較高者。

上述兩種方法結合,可互補不足。
发表于 2005-6-5 16:35:59 | 显示全部楼层
受益匪浅
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|湘里妹子学术网 ( 粤ICP备2022147245号 )

GMT++8, 2024-5-6 20:15 , Processed in 0.066344 second(s), 17 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表