文字列が「Unicode 的にバグっているか」チェックする関数 isWellFormed について

サロゲートペアを含む文字(絵文字など)を分解し、その一部を文字とみなして再利用したとき、バグった文字列が生まれる可能性があります。

const word = '😀'
const items = word.split('')

console.log(items)
// ['\uD83D', '\uDE00']

const array = ['A', 'B', items[0], 'C']

const text = array.join('')

console.log(text)
// AB�C

プログラマーは一生に何回か�を見ます。😀は二つのコードポイントからなるため、split(‘’) で「そのままでは文字にならないコードポイント」に分解されます。

分解された二つのコードポイントは上位サロゲートと下位サロゲートと呼ばれます。

D83D 上位サロゲート
DE00 下位サロゲート

上位サロゲートと下位サロゲートは単体で文字にならず、ペアになって初めて文字になります。

上例のように、上位サロゲートまたは下位サロゲートを単体で文字列に組みこむと、その文字列はバグってしまいます。

サロゲートの扱いをミスって文字列がバグっているか確かめる方法

コードポイントの操作をする場合、文字列がおかしくなっているか確かめたくなります。そのときは isWellFormed を使います。

const word = '😀'
const items = word.split('')

console.log(items)
// ['\uD83D', '\uDE00']

const array = ['A', 'B', items[0], 'C']

const text = array.join('')

console.log(text)
// AB�C

let isGoodText = true

if (text.isWellFormed()) {
	isGoodText = true

} else {
	isGoodText = false
}

console.log(isGoodText)
// false

isWellFormed は孤立サロゲート(ペアになっていない上位サロゲートまたは下位サロゲート)の存在をチェックする関数です。

�があるかないかを確かめる簡易的な関数で、正規表現とコードポイントを使って文字列を変形するさいに重宝します。