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
#テキストエディター
#エディター
冷やかしの「いいね」は断ります!