本記事は「IVS登録の異体字を常用漢字に置換したい(知識編)」の続きである。
エクセルにおけるIVS登録文字の扱い
シートに張り付けた場合
赤色の文字がIVS登録文字。文字長はLen()を、文字長(Byte)にはLenB()を充てている。Variation Selectorが別の文字として扱われるため、Variation Selector無しより、文字長が長くなっている。通常の文字1つにつきVariation Selectorを表す文字が2文字かつ2バイト付与されていることが分かる。
VBAエディタに張り付けた場合
エディタでは、Shift-JIS上表現できない文字は全て文字化けを起こすため、張り付けると「辻??本迅??田」となる。?は文字コード「2F」の単なるクエスチョンマークであり、枝番としての情報が欠落するため、エディタに直接文字を張り付けて処理をすることはできない。(シートから読み取る必要がある)
実装コード
Option Explicit
' UCS(Universal Coded Character Set)に登録された文字のVariation Selectorを取り除く
' 例.にしんにょうの辻 :8FBB
' いっしんにょうの辻 :8FBB + E0100(VS)
' 「+E01○○」のVSが環境依存文字として判定されるため削除する必要がある
Public Function Remove(str As String, ByRef replaceMap As Dictionary) As String
Const REPLACED_MARK As Long = &H0
Dim i As Long
For i = 1 To Len(str) - 2
Dim c As String
Dim n1 As String
Dim n2 As String
Dim code1 As String
Dim code2 As String
c = Mid(str, i, 1)
n1 = Mid(str, i + 1, 1)
n2 = Mid(str, i + 2, 1)
If (IsVariationSelector(n1, n2)) Then
Call replaceMap.Add(c & n1 & n2, c)
Mid(str, i + 1, 1) = Chr(REPLACED_MARK)
Mid(str, i + 2, 1) = Chr(REPLACED_MARK)
i = i + 2
End If
Next
' Variation Selectorを全て取り除く
str = Replace(str, Chr(REPLACED_MARK), "")
Remove = str
End Function
' 指定文字がVariation Selectorであるか
Private Function IsVariationSelector(c1 As String, c2 As String) As Boolean
Dim code1 As String
Dim code2 As String
code1 = AscW(c1)
code2 = AscW(c2)
' Variation Selectorの取りうるコードポイントの範囲に含まれるか
' U+E0100 - U+E01EF
If (code1 = &HDB40 And (&HDD00 <= code2 And code2 <= &HDDEF)) Then
IsVariationSelector = True
Else
IsVariationSelector = False
End If
End Function
解説
対象の文字がIVS登録文字であるかを判定するとき、各文字の文字コードは確認していない。代わりにVariation Selectorの文字コードであれば、その直前の文字はIVS登録文字であると判定できる。
Variation Selectorの取りうる範囲はU+E0100 – U+E01EFであるが、これはUTF-8の場合である。VBA上でコードポイントを扱う時はUTF-16であるため、取りうる範囲は1バイト目が「DB40」固定、2バイト目が「DD00~DDEF」である。その条件を満たした場合、Variation Selectorを表す2文字・4バイトをReplaceにより取り除いている。
処理速度
300,000件:3.9秒
1,000件:0.013秒
データの10%にIVS登録文字が含まれるとして、その処理速度は上記の通り。