ElectronでGoogleSpreadSheetやGoogleDriveからデータを取得して、文字列の一致判定で濁点が含まれる文字の場合、見た目は同じだけど別の文字として判定されてしまうケースが出てしまった。
見た目は一緒だけど不一致になる濁点カタカタ
ElectronからGoogle SpreadSheetに結果を出力すると、確かに見た目は一緒だけど、SpreadSheetの文字検索でも一致とはならないし、コピーしてVSCodeやSublimeでテキスト検索を試しても別の文字として判定される。
試しにjsで試すとこんな感じ
Welcome to Node.js v15.4.0.
Type ".help" for more information.
> let a = 'ジ'
undefined
> let b = 'ジ'
undefined
> a == b
false
濁点文字の文字コード
調べてみると、UTFとSJISとかのい問題ではなく、UTFの中でも濁点ありには複数あって、濁点を含んだ文字か、濁点が追加された文字か?の違いだった。
escapeでコードを確認すると「し」の濁点ありでも、コードも長さも異なる。
> escape(a)
'%u30B8'
> escape(b)
'%u30B7%u3099'
> a.length
1
> b.length
2
String.normalize( NFC/NFD )
これはstring.normalizeで統一することができるようで、NFCとNFDを指定することで任意の型式に変換できる。
今回はSpreadSheetやDriveからの文字取得時にはNFCに統一する型式にして回避
> escape(a.normalize('NFC'))
'%u30B8'
> escape(b.normalize('NFC'))
'%u30B8'
> escape(a.normalize('NFD'))
'%u30B7%u3099'
> escape(b.normalize('NFD'))
'%u30B7%u3099'