Board logo

標題: [發問] 如何判斷是否 全形字? [打印本頁]

作者: sunnyso    時間: 2013-4-8 20:15     標題: 如何判斷是否 全形字?

本帖最後由 sunnyso 於 2013-4-8 20:17 編輯

如何判斷是否 全形字? 有沒有用 VBA 和不用VBA的方法.  謝謝

用=CODE() 對"氹" 字 沒有用

[attach]14588[/attach]
  1. 字        is全形
  2. 氹        TRUE
  3. 仔        TRUE
  4. 澳        TRUE
  5. A        FALSE
  6. 1        FALSE
  7. 1        TRUE
  8. ?        FALSE
  9. ?        TRUE
  10. .        FALSE
  11. 。        TRUE
複製代碼
[attach]14589[/attach]
作者: Hsieh    時間: 2013-4-9 09:03

回復 1# sunnyso
一般而言,字串的字碼對應字元與顯示字串不同時(如繁體系統顯示簡體文字)
氹(ㄍㄢ)字使用CODE函數取得的字元碼是63
63對應的字串是?(問號)
以此為依據,顯示與對應不同則屬於中文字為全型字
不在0~127字碼表內的文字也屬於全型字(128~255是否屬於全型?)
得到的規則
B2=OR(CHAR(CODE(A2))<>TEXT(A2,"@"),CODE(A2)<0,CODE(A2)>127)
是否還有其他規則屬於全型,還請各位指正

    [attach]14597[/attach]
作者: sunnyso    時間: 2013-4-9 10:15

謝謝,  code() 會小於0 嗎?若會什麼情況?
作者: Hsieh    時間: 2013-4-9 10:28

回復 3# sunnyso
應該是沒有
就少個判斷條件吧
=OR(CHAR(CODE(A2))<>TEXT(A2,"@"),CODE(A2)>127)
作者: ML089    時間: 2013-4-9 15:28

ASCII CODE 不是<=255 ?

全字型應該是指說雙元字型
一般用 LENB() 來判斷是否為全字型

但 氹 個字用 LENB("氹") = 1, 這可打破以往的想法

由下列兩式看出EXCEL處理方法也出現不一致性,"氹" 用MIDB出現2的字元,用LENB指出現1個字元
=MIDB("氹123",{1,2,3,4,5,6},1) ={" "," ","1","2","3",""}
=LENB(MID("氹123",{1,2,3,4,5,6},1)) ={1,1,1,1,0,0}
作者: sunnyso    時間: 2013-4-9 16:23

我本來也是用 >255 來判斷, doublebyte字

未知是否 Excel 的 bug
作者: ANGELA    時間: 2013-4-10 09:24

回復 5# ML089


    有很多古字或少用的字用code()查詢會得到63的字,用lenb()查都會得到1
作者: ML089    時間: 2013-4-10 09:53

回復 4# Hsieh

    =OR(CHAR(CODE(A2))<>TEXT(A2,"@"),CODE(A2)>127)

單字元測試第一字元是否為全字型
=OR(CHAR(CODE(A2))<>A2$"",LENB(A2)=2)

多字元測試第一字元是否為全字型
如果以 CODE() 取第一字之特性,可以用 LEFT() 來匹配
=OR(CHAR(CODE(A2))<>LEFT(A2),LENB(LEFT(A2))=2)
作者: ML089    時間: 2013-4-10 09:59

回復 7# ANGELA

所以全形字的判斷就變得更複雜

樓主也太厲害,找出 氹 字,LENB()=1

不知哪裡可以找出這些字碼,再測試哪些字碼LENB()=1
作者: sunnyso    時間: 2013-4-10 12:04

回復 9# ML089




作者: ML089    時間: 2013-4-10 12:22

回復 10# sunnyso


    請問你怎樣找出這些字?
作者: sunnyso    時間: 2013-4-10 12:56

回復 11# ML089

廣東話(粵語)口語字
作者: ML089    時間: 2013-5-8 14:37

本帖最後由 ML089 於 2013-5-8 14:39 編輯

我認為 ASCII CODE 0~255 為單字元,其他以外都稱為雙字元比較簡單
單字元特性 LEFT()與LEFTB()取值應該相同
用 =LEFTB(A2)<>LEFT(A2) 來判斷TRUE為雙字元,FALSE為單字元


於實務上運用範例
R3 ="氹仔澳A1??"
有4個全型字, 注意 "氹" 特別字元 LENB()=1

計算全型字公式
=SUMPRODUCT(--(MID(R3,ROW(1:9),1)<>LEFTB(MID(R3,ROW(1:9),1))))
=4
作者: sunnyso    時間: 2013-5-8 16:43

回復 13# ML089

感謝大大, 這是最簡潔 的判斷。
作者: shan0948    時間: 2013-5-20 21:51

請教前輩,程式在執行時遇到全形或半形字會出現不同的結果嗎?
作者: 准提部林    時間: 2013-5-21 09:51

參考看看:
=BIG5(A2)=A2

大凡〔特殊字.罕用字.自造字〕:
CODE為63,LENB為1,
放在VBE時,顯示"?"
較常見字,如:〔堃〕
作者: ML089    時間: 2013-5-21 15:57

回復 16# 准提部林

BIG5 函數將半形字元轉換成全形 (雙位元組) 字元
A2為一個字元情況判斷是否為 全字型
用  =BIG5(A2)=A2 來判斷也是好方法,但仍需注意空字元 "" 及空格的判斷
作者: sunnyso    時間: 2013-5-21 16:15

又長知識了
謝謝
作者: 准提部林    時間: 2013-5-21 21:04

計算〔全型字〕字元數:
A1:氹堃仔澳A12135k??
B1:=LEN(A1)+LENB(A1)-LENB(BIG5(A1))

以前從沒考慮特殊文字,此題出得好!
作者: ML089    時間: 2013-5-21 21:33

本帖最後由 ML089 於 2013-5-21 21:36 編輯

回復 19# 准提部林


    讚讚讚!
    這應該是創新公式

註解一下,以免日後要忘記
B:全型字數
S:半型字數
B1:=LEN(A1)+LENB(A1)-LENB(BIG5(A1))
B1:=B+S + B*2+S - (B*2 + S*2)
B1:=B + (B*2+S*2) - (B*2 + S*2)
B1:=B
作者: Bodhidharma    時間: 2013-5-22 03:52

回復 20# ML089

補充一下註解,應該加一個
X:應視為是全型,但LENB()為1的特例,如「堃」
B:全型字數
S:半型字數
LEN(A1)+LENB(A1)-LENB(BIG5(A1))
=(B+S +X)+ (B*2+S+X) - (B*2 + S*2+X)
=B+X
作者: ML089    時間: 2013-5-22 09:18

回復 21# Bodhidharma

沒錯,你的說明比較對,重點就是 X
作者: sunnyso    時間: 2013-5-26 21:50

回復 2# Hsieh
回復 13# ML089
回復 19# 准提部林
回復 21# Bodhidharma

Left(   ,1) <> LeftB(   , 1) 在VBA好像不能用

附註 LeftB 函數是使用在位元組資料字串上。所以 LeftB 傳回的是位元組數,而非字元數。

請問各位大大, 如何用VBA來判斷(不使用Application.WorksheetFunction)?
作者: 准提部林    時間: 2013-5-27 22:56

回復 23# sunnyso


∼∼LeftB(   , 1) 在VBA好像不能用___〔LeftB〕在工作表函數與VBA函數作用不同,只能使用〔Evaluate〕來帶!

A1文字:氹仔 堃 澳A1??2135H?V

1.以MID跑迴圈取字,再逐一比對:
  Sub 全型字元數1()
  Dim j%, Jm%, T$
  For j = 1 To Len([A1])
    T = Mid([A1], j, 1)
    If T <> Evaluate("LeftB(""" & T & """,1)") Then Jm = Jm + 1
  Next j
  MsgBox "全型字共有:" & Jm & " 個"
  End Sub
 
2.不用迴圈:
  Sub 全型字元數2()
  Dim X1%, X2%
  X1 = Len([A1])
  X2 = Evaluate("Len(LeftB(""" & [A1] & String(X1, "1") & """," & X1 * 2 & "))")
  MsgBox "全型字共有:" & X1 * 2 - X2 & " 個"
  End Sub
 
  公式演示:
  B1:=LEN(A1)*2-LEN(LEFTB(A1&REPT(1,LEN(A1)),LEN(A1)*2))
 
  其他參考:文字若超過99字,請自行調整
  =LEN(A1)*2-LEN(LEFTB(A1&REPT(1,99),LEN(A1)*2)) 
  =FREQUENCY(LEN(LEFTB(MID(A1,ROW(1:99),1)&"TT",2)),{1,0})
  =SUMPRODUCT(N(LEN(LEFTB(MID(A1,ROW(1:99),1)&"TT",2))=1))
  
  若不考慮〔特殊字〕應會單純些,以上粗略程式碼及公式供參考,看版主們是否再提供較正規的精闢解法!
作者: sunnyso    時間: 2013-5-31 00:49

回復 24# 准提部林

若不考慮〔特殊字〕

DblChrCount = LenB(StrConv([D3], vbFromUnicode)) - Len([D3])
作者: sunnyso    時間: 2013-5-31 01:10

回復 2# Hsieh 回復 21# Bodhidharma 回復 22# ML089 回復 24# 准提部林

終於想到一個簡潔的方法,用 “正規表示式”

不知 各位大大們是否再提供更的精闢解法!
  1. Function CountDblChr(ByVal sCh As String) As Integer
  2.     Set re = CreateObject("vbscript.regexp")
  3.     're.Pattern = "[\u4e00-\u9fa5]" '判斷中文字(包括特殊字,但不包括符號。和數字如1)
  4.     re.Pattern = "[^\x00-\xff]" '判斷所有的全形字
  5.     re.Global = True
  6.     re.IgnoreCase = True
  7.     Set matches = re.Execute(sCh)
  8.     CountDblChr = matches.Count
  9.     Set re = Nothing
  10. End Function
複製代碼

作者: cbl0924    時間: 2013-6-29 22:30

可不可以乾脆全部都用 =BIG5(數值/文字)
全部統一變成全形
或 =ASC(數值/文字)  全部變成半形

這樣會不會比較簡單??
作者: sunnyso    時間: 2013-6-29 23:54

回復 27# cbl0924

BIG5對 特殊字無效(例如氹)
作者: linyancheng    時間: 2014-2-10 17:33

現在Unicode碼應用很廣,Excel對Unicode碼支援不全(至少不便),尤其是VBA。還有也不支援Unicode碼的CSV檔。




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)