S-JIS 半角文字と全角文字の判定 手探り編 4:2024/08/06

S-JIS 半角文字と全角文字の判定部分:テスト用
VBA

低機能エディターに必要になる、半角と全角の判定を
手探りでプログラム化する。その4。
ようやく1行をループで判定することができた。

-----------------------

Shift-JIS文字コード Wikipediaより:

2バイト文字は、
第1バイトに 81-9FまたはE0-EF
第2バイトに 40-7Eまたは80-FC

Shift-JIS-2004では、
第1バイトに 81-9FまたはE0-EF、F0-FC
第2バイトに 40-7Eまたは80-FC

注:
2バイト目が 5C("\")になる文字では問題が起きることがある。

-----------------------

これをSelect Case文でプログラム化してみた。
今回は
' テスト用S-JIS文字列をループで
' 判断させてみる。

Public Sub test()
'    Dim PointerX AS Integer

    '半角全角フラグ
'    Dim HanZenFlag AS Byte
' 半角文字:      半角全角フラグ = 0
' 全角文字 第1バイト:半角全角フラグ = 1
' 全角文字 第2バイト:半角全角フラグ = 2

'   それ用の配列も必要。
'    Dim HZArray(200) AS Byte
'    Dim HZArray(9999, 200) AS Byte

'-----------------------
Dim Ch1st, Ch2nd AS Byte

Dim UnStr As String
Dim SjStr As String

    Dim HanZenFlag(200) AS Byte

UnStr = "ab123"
' Unicode文字列  10バイト
' MsgBox UnStr & "バイト数" & LenB(UnStr)

SjStr = StrConv(UnStr, vbFromUnicode)
' S-JIS文字列  8バイト
' MsgBox SjStr & "バイト数" & LenB(SjStr)

SjStr = Sjstr & ChrB(&HD) & ChrB(&HA)
' 末尾に改行を追加したテスト用S-JIS文字列。

'-----------------------
' 判定プログラムが正しいかどうかをテスト。

' テスト用S-JIS文字列をループで判断させてみる。

' 以下イミディエイトWindowに表示
Dim I As Byte

'ループ開始

    PointerX = 1  '先頭バイトから
' For I = 1 To 4
    Do 

' S-JIS文字列の最短は2バイトのはず。
' 2文字が &H0D, &H0A なら行末

'    Ch1st = ( MidB(SjStr, PointerX, 1) )     '"a"
     Ch1st = AscB( MidB(SjStr, PointerX, 1) ) ' &H97
' Debug.Print "Ch1st =  " & Ch1st 

    PointerX = PointerX + 1
' このとき、PointerXは2バイト目を示している。

'    Ch2nd = ( MidB(SjStr, PointerX, 1) ' "b"
     Ch2nd = AscB( MidB(SjStr, PointerX, 1) ) ' &H98
' Debug.Print "Ch2nd =  " & Ch2nd

Debug.Print "Ch1st = &H" & Hex(Ch1st) & "  Ch2nd = &H" &  Hex(Ch2nd)

    Debug.Print "0 PointerX = " & PointerX

' 判定の構造を少し入れ替えました。

        Select Case Ch1st
'    -------------------------------------------------
            Case &H81 To &H9F, &HE0 To &HEF
'                -------------------------------------------------
                Select Case Ch2nd
                    Case &H40 To &H7E, &H80 To &HFC
            ' 最初のバイトの半角全角フラグ = 1
                    HanZenFlag(PointerX-1) = 1
'        Debug.Print "HanZenFlag(-1) = " & HanZenFlag(PointerX-1)
            ' 次のバイトの半角全角フラグ  = 2
                    HanZenFlag(PointerX) = 2
'        Debug.Print "HanZenFlag = " & HanZenFlag(PointerX)
' 次の1行を加えた!! 08/06 21:21
                PointerX = PointerX + 1

                    Debug.Print "全角 2 PointerX = " & PointerX

                    Case Else ' 半角と判定。
            ' 最初のバイトの半角全角フラグ = 0
                    PointerX = PointerX - 1
                    HanZenFlag(PointerX) = 0
'        Debug.Print "HanZenFlag(-1) = " & HanZenFlag(PointerX-1)
                    Debug.Print "半角 3 PointerX = " & PointerX
                    End Select
'                -------------------------------------------------

            Case Else ' 半角と判定。
' 先頭や末尾が改行コードの場合:
                If (Ch1st = &H0D) and (Ch2nd = &H0A) Then    
                ' 最初のバイトの半角全角フラグ = 0
                    HanZenFlag(PointerX-1) = 0
        '        Debug.Print "HanZenFlag(-1) = " & HanZenFlag(PointerX-1)
                ' 2番目のバイトの半角全角フラグ = 0
                    HanZenFlag(PointerX) = 0
'        Debug.Print "HanZenFlag = " & HanZenFlag(PointerX)

'        Debug.Print "1 PointerX = " & PointerX
'-------------------------------------------------
' これはやめる。    PointerX = 1  
' 初期化しない。
'-------------------------------------------------
                Debug.Print "改行 1 PointerX = " & PointerX
'                Goto ExitDo
' Gotoは構造化プログラムには使いたくない!
                End If

    ' それ以外の場合は
            ' 最初のバイトの半角全角フラグ = 0

                    HanZenFlag(PointerX) = 0
'        Debug.Print "HanZenFlag(-1) = " & HanZenFlag(PointerX-1)
                    Debug.Print "半角 4 PointerX = " & PointerX
            End Select
'    -------------------------------------------------

            Debug.Print "Loop End " 
            Debug.Print " "

    Loop While ( LenB(SjStr) > PointerX )
' 注意:ここ、>= ではダメ。

For I = 1 To 10
        Debug.Print "I = " & I & "  HanZenFlag(I) = " & HanZenFlag(I)
Next I
' Next I
End Sub


For Nextループでテスト。
08/06 
全角判定するところにバグがあった。
                PointerX = PointerX + 1
この1行不足していた。
その結果、次の全角を半角と誤認していた。
修正前:
 Ch1st = &H82 Ch2nd = &H50
 0 PointerxX = 4
 全角 2 PointerX = 4
 Loop End

 Ch1st = &H50 Ch2nd = &H82
 0 PointerxX = 5
 半角 4 PointerX = 5
 Loop End

修正後:
 Ch1st = &H82 Ch2nd = &H50
 0 PointerxX = 4
 全角 2 PointerX = 5
 Loop End

 Ch1st = &H82 Ch2nd = &H51
 0 PointerxX = 6
 全角 2 PointerX = 7
 Loop End

これも、修正でうまく動作した。
HanZenFlag()も、ちゃんと動作した。
0 0 1 2 1 2 1 2 0 0


#VisualBasic
#VBA
#テキストエディター
#エディター
冷やかしの「いいね」は断ります!