關於 字元 的 半形 / 全形 轉換

關於 字元 的 半形 / 全形 轉換

關於 字元 的 半形 / 全形 轉換

<< VB.Net >>

Imports System.Text

Public Class Form1

' 如何判斷輸入的字元是 "全形" 或 "半形" ?

' 方法 1

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _

Handles TextBox1.KeyPress

' 判斷輸入字元的 ASCII 字元碼之 16 進位長度 , 2 為半形

If Hex(Asc(e.KeyChar)).Length = 2 Then

MessageBox.Show("半形字元")

Else

MessageBox.Show("全形字元")

End If

End Sub

' KeyPressEventArgs.KeyChar 屬性 : 取得對應於所按下按鍵的字元。

' Hex 函式 : 傳回代表數字十六進位值的字串。

' Asc 函式 : 傳回Integer 值,表示與字元對應的字元碼。

' Asc 會傳回輸入字元的「字碼指標」(Code Point) 或字元碼。

' 這可以是值從 0 到 255 的單一位元組字元集 ( Single-Byte Character Set,SBCS ),

' 和值從 -32768 到 32767 的雙位元組字元集 ( DBCS )。

' ASCII 字碼表含有擴充 ASCII (American Standards Committee for Information Interchange)

' 字元集的 十進位 和 十六進位值。

' 擴充字元集包括 ASCII 字元集和 128 個繪製圖形和線條的其他字元,通常稱為「IBM 字元集」。

' 在Windows 中,字碼大於 127 的字元,其顯示會依選取的字體而不同。

' ================================================================

' 方法 2

Private Sub TextBox2_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _

Handles TextBox2.KeyPress

' 判斷輸入字元於 Unicode 編碼時的 第二個位元組 若是 255 則是 全形, 反之則為 半形

If Encoding.Unicode.GetBytes(e.KeyChar)(1) = 255 Then

MessageBox.Show("全形字元")

Else

MessageBox.Show("半形字元")

End If

' PS : 此方法不適用於 中文字

End Sub

' System.Text 命名空間 Encoding 類別

' Unicode 屬性 : 以 Little-Endian 位元組順序取得 UTF-16 格式的 編碼方式。

' GetBytes 方法 : 在衍生類別中覆寫時,將字元集編碼成位元組序列。

' ================================================================

' 如何將使用者所輸入的 全形字元 轉成 半形字元 ?

' 方法 1

Private Sub TextBox3_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _

Handles TextBox3.KeyPress

Dim KeyAscii As Short = Asc(e.KeyChar)

If KeyAscii < 0 Then e.KeyChar = Chr(Asc(StrConv(Chr(KeyAscii), VbStrConv.Narrow)))

' StrConv 函式 : 傳回依照指定方式轉換的字串。

' VbStrConv.Narrow : 將字串中的 全形字元 轉換為 半形字元。

End Sub

' KeyPressEventArgs.KeyChar 屬性 : 設定對應於所按下按鍵的字元。

' Chr 函式 : 傳回與指定字元碼關聯的字元 ; Chr 的有效範圍是 0 到 255。

' Public Function Chr(ByVal CharCode As Integer) As Char

' CharCode : 代表字元的「字碼指標」或 字元碼的 Integer 運算式。

' 如果 CharCode 不在有效範圍內,則會發生 ArgumentException 錯誤。

' 如何將使用者所輸入的 半形字元 轉成 全形字元 ?

Private Sub TextBox4_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _

Handles TextBox4.KeyPress

Dim KeyAscii As Short = Asc(e.KeyChar)

If KeyAscii > 0 Then e.KeyChar = Chr(Asc(StrConv(Chr(KeyAscii), VbStrConv.Wide)))

' VbStrConv.Wide : 將字串中的 半形字元 轉換為 全形字元 。

End Sub

' ================================================================

' 如何將使用者所輸入的 全形字元 轉成 半形字元 ?

' 方法 2

Private Sub TextBox5_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _

Handles TextBox5.KeyPress

Dim byt() As Byte = Encoding.Unicode.GetBytes(e.KeyChar)

If byt(1) = 255 Then ' 若第二個位元組是 255 , 則將 全形 轉 半形

byt(0) = byt(0) + 32 ' 第一個位元組 + 32

byt(1) = 0 ' 第二個位元組設為 0

e.KeyChar = Encoding.Unicode.GetChars(byt)(0)

End If

End Sub

' System.Text 命名空間 Encoding 類別

' Unicode 屬性 : 以Little-Endian 位元組順序取得 UTF-16 格式的編碼方式。

' GetChars 方法 : 在衍生類別中覆寫時,將位元組序列解碼成字元集。

' 如何將使用者所輸入的 半形字元 轉成 全形字元 ?

Private Sub TextBox6_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _

Handles TextBox6.KeyPress

Dim byt() As Byte = Encoding.Unicode.GetBytes(e.KeyChar)

If byt(1) = 0 Then ' 若第二個位元組是 0 , 則將 半形 轉 全形

byt(0) = byt(0) - 32 ' 第一個位元組 - 32

byt(1) = 255 ' 第二個位元組設為 255

e.KeyChar = Encoding.Unicode.GetChars(byt)(0)

End If

End Sub

End Class

' ================================================================

全型 / 半型 轉換 Function 供參考

' 半型 轉 全型

Public Function Narrow2Wide(ByVal data As String) As String

Return String.Join("", Array.ConvertAll(Of Char, String)(data.ToCharArray, AddressOf Cvt_N_2_W))

End Function

Private Function Cvt_W_2_N(ByVal c As Char) As String

Dim byt() As Byte = Encoding.Unicode.GetBytes(c)

If byt(1) = 255 Then Return Encoding.Unicode.GetString(New Byte() {byt(0) + 32, 0}) Else Return c

End Function

' --------------------------------------------------------------------------------------------------------------------

' 全型 轉 半型

Public Function Wide2Narrow(ByVal data As String) As String

data = data.Replace("〔", "[").Replace("〕", "]").Replace("'", "'").Replace(" ", " ")

Return String.Join("", Array.ConvertAll(Of Char, String)(data.ToCharArray(), AddressOf Cvt_W_2_N))

End Function

Private Function Cvt_N_2_W(ByVal c As Char) As String

Dim byt() As Byte = Encoding.Unicode.GetBytes(c)

If byt(1) = 0 Then Return Encoding.Unicode.GetString(New Byte() {byt(0) - 32, 255}) Else Return c

End Function

' --------------------------------------------------------------------------------------------------------------------

' 半型 轉 全型

Public Function ToWchr(ByRef data As String) As String

Dim sb As New StringBuilder

Dim ascii As Integer = 0

For Each c As Char In data.ToCharArray()

ascii = Convert.ToInt32(c)

If ascii = 32 Then

sb.Append(Convert.ToChar(12288))

Else

sb.Append(Convert.ToChar(ascii + IIf(ascii < 127, 65248, 0)))

End If

Next

Return sb.ToString

End Function

' --------------------------------------------------------------------------------------------------------------------

' 全型 轉 半型

Public Function ToNchr(ByRef data As String) As String

Dim sb As New StringBuilder

Dim ascii As Integer = 0

For Each c As Char In data.Replace("〔", "[").Replace("〕", "]").Replace("'", "'").ToCharArray()

ascii = Convert.ToInt32(c)

If ascii = 12288 Then

sb.Append(Convert.ToChar(32))

Else

If ascii > 65280 And ascii < 65375 Then

sb.Append(Convert.ToChar(ascii - 65248))

Else

sb.Append(Convert.ToChar(ascii))

End If

End If

Next

Return sb.ToString

End Function

PS :

半形 空格 ASCII 為 32 , 全形 空格 ASCII 為12288

其他字元 半形ASCII 33~126 與 全形ASCII 65281~65374 對應之 ASCII 皆相差 65248

全形符號 〔 〕' 轉 半型時 ASCII 對應關係不同 , 因此直接用 Replace 做處理

' ================================================================

<< VB6 >>

' 如何判斷輸入的字元是 "全形" 或 "半形" ?

' 方法 1

Private Sub Text1_KeyPress(KeyAscii As Integer)

Dim strChr As String

strChr = Chr(KeyAscii)

If LenB(strChr) = LenB(StrConv(strChr, vbFromUnicode)) Then

MsgBox "全形字元"

Else

MsgBox "半形字元"

End If

End Sub

' Chr 函數 : 傳回一個含有與指定的字元碼相關之字元的 String。

' 語法

' Chr (charcode)

' charcode 引數是一個用來識別某字元的Long。

' 請注意 : 0 到 31 之間的數字與一般、非列印的ASCII碼相同,例如,Chr(10) 會傳回換行字元。

' charcode 的正常範圍為 0-255。然而,在DBCS系統,charcode 的實際範圍為 -32768 到 65535。

' LenB 函數 : 傳回一Long,為儲存一變數所需的位元組數。

' 語法

' Len(string | varname)

' string 為任何正確的字串運算式。如果 string 所含為 Null,會傳回Null。

' Varname 為任何正確的變數名稱。如果 varname 所含為 Null,會傳回 Null。

' 如果 varname 是Variant,Len 會視其為 String並且傳回其所含之字元數。

' 請注意 : 兩引數必須有其一 (而且只能有一)。如為使用者自訂型態,,Len 會傳回其寫至檔案的大小。

' LenB 函數是使用在位元組資料字串上,如同在雙位元組字元集 (DBCS) 語言中一樣。

' 所以 LenB 傳回的是位元組位置,而非字元位置。

' 如為使用者自訂型態,LenB 會傳回在記憶體中之大小,包括元件之間的間隙。

' StrConv 函數 : 傳回一特定轉換後的 Variant (String)。

' 語法

' StrConv(string, conversion, LCID)

' string 必要引數。為欲轉換的字串運算式。

' conversion 必要引數:為Integer。其值的和決定轉換的型態。

' string 必要引數。為欲轉換的字串運算式。

' LCID 選項的。如果與系統LocaleID不同,則為LocaleID(系統LocaleID為缺省值。)

' conversion 引數的設定:

' vbFromUnicode ( 128 ) : 將字串由 Unicode 轉成系統的預設字元碼對應頁。

' vbUnicode ( 64 ) : 據系統的預設字元碼對應頁將字串轉成 Unicode。

' vbWide ( 4 ) : 將字串中單位元組字元轉成雙位元組字元。 ( 適用於遠東地區 )

' vbNarrow ( 8 ) : 將字串中雙位元組字元轉成單位元組字元。 ( 適用於遠東地區 )

' ================================================================

' 方法 2

Private Sub Text2_KeyPress(KeyAscii As Integer)

Dim strChr As String

Dim byt() As Byte

strChr = Chr(KeyAscii)

byt = StrConv(strChr, vbFromUnicode)

If byt(0) > 128 Then

MsgBox "全形字元"

Else

MsgBox "半形字元"

End If

Erase byt

End Sub

' ================================================================

' 方法 3

Private Sub Text3_KeyPress(KeyAscii As Integer)

If Len(Hex(KeyAscii)) > 2 Then

MsgBox "全形字元"

Else

MsgBox "半形字元"

End If

End Sub

' ================================================================

' 方法 4

Private Sub Text4_KeyPress(KeyAscii As Integer)

Dim strChr As String

strChr = Chr(KeyAscii)

If LenB(StrConv(strChr, vbFromUnicode)) = 2 Then

MsgBox "全形字元"

Else

MsgBox "半形字元"

End If

End Sub

' ================================================================

' 方法 5

Private Sub Text5_KeyPress(KeyAscii As Integer)

Dim strChr As String

Dim byt() As Byte

strChr = Chr(KeyAscii)

byt = StrConv(strChr, vbFromUnicode)

If UBound(byt) = 1 Then

MsgBox "全形字元"

Else

MsgBox "半形字元"

End If

Erase byt

End Sub

' UBound 函數 : 傳回 Long值,表示指定陣列某維最大可使用的陣列索引。

' 語法

' UBound(arrayname[, dimension])

' arrayname 必要的引數。陣列變數的名稱,遵循標準變數命名規格。

' dimension 選擇性引數。Variant (Long),表示傳回的是那一維的上限。

' 1 表示第一維,2 表示第二維,依此類推。如果省略 dimension,則預設是 1。

' Erase 陳述式 : 重新初始化固定大小陣列的元素,並釋放動態陣列的儲存空間。

' ================================================================

' 半形字元 轉換 全形字元

Private Sub Text6_KeyPress(KeyAscii As Integer)

Dim strChr As String

strChr = Chr(KeyAscii)

KeyAscii = Asc(StrConv(strChr, vbWide))

End Sub

' ================================================================

' 全形字元 轉換 半形字元

Private Sub Text7_KeyPress(KeyAscii As Integer)

Dim strChr As String

strChr = Chr(KeyAscii)

KeyAscii = Asc(StrConv(strChr, vbNarrow))

End Sub

' Asc 函數 : 傳回一個 Integer,為字串中第一個字母的字元碼。

' 語法

' Asc(string)

' string 引數是任何可用的字串運算式。若是 string 中沒有包含任何字元,則會產生執行階段錯誤。

' 請注意

' 在非雙位元組字元集系統下,其傳回範圍為 0 - 255。 若在雙位元組字元集系統下,則為 -32768 - 32767。

' 附註 AscB 函數是用來處理包含位元組資料的字串,AscB 會傳回第一個位元組,而非第一個字元的字元碼。

' AscW 函數會傳回Unicode字元碼,若平台不支援Unicode,則與Asc函數功能相同。