どうも。
気づけば、一年以上記事書いてなかった。
普通に死ぬほど忙しかった。
さて、表記の件だ。
面白いよね、絵文字って。
エンジニアにとっては、56したい存在だけどね。
DBに保存する情報や、印刷に回すデザイン情報などは特に、絵文字が入っていると、まず間違いなくバグるので、
非常に厄介な存在だ。
そして、その性質が故に、除去がとんでもなく難しいのでことさら56したくなる。
こればっかりはやってみた人間にしかわからない。
ってわけで、御託ここまで。
絵文字の完璧な除去になったのでは?
ってコードができたので、公開しようかと。
const ranges = [
'[\ud800-\ud8ff][\ud000-\udfff]', // 基本的な絵文字除去
'[\ud000-\udfff]{2,}', // サロゲートペアの二回以上の繰り返しがあった場合
'\ud7c9[\udc00-\udfff]', // 特定のシリーズ除去
'[0-9|*|#][\uFE0E-\uFE0F]\u20E3', // 数字系絵文字
'[0-9|*|#]\u20E3', // 数字系絵文字
'[©|®|\u2010-\u3fff][\uFE0E-\uFE0F]', // 環境依存文字や日本語との組み合わせによる絵文字
'[\u2010-\u2FFF]', // 指や手、物など、単体で絵文字となるもの
'\uA4B3', // 数学記号の環境依存文字の除去
];
const surrogatePairCode = [
65038,
65039,
8205,
11093,
11035
];
const removeEmoji = in_value => {
const reg = new RegExp(ranges.join('|'), 'g');
let retValue = in_value.replace(reg, '');
// パターンにマッチする限り、除去を繰り返す(一回の正規表現除去では除去しきないパターンがあるため)
while (retValue.match(reg)) {
retValue = retValue.replace(reg, '');
}
// 二重で絵文字チェック(4バイト、サロゲートペアの残りカス除外)
return retValue.split('').reduce((p, c) => {
const code = c.charCodeAt(0);
if (
encodeURIComponent(c).replace(/%../g, 'x').length < 4 &&
!surrogatePairCode.some(codeNum => code == codeNum)
) {
return p += c;
} else {
return p;
}
}, '');
}
const target = document.getElementsByClassName('removeEmoji');
const bindFunc = function(){
this.value = removeEmoji(this.value);
};
Array.prototype.forEach.call(target, el => {
el.addEventListener('change', bindFunc);
el.addEventListener('blur', bindFunc);
});
ポイントは、
正規表現の部分と、サロゲートペアの残りカスの除去だ。
多くの絵文字除去の方法記事で採用されている、正規表現を簡潔にし、アップデートしている。
これにより、9割がたの除去がされる。
また、マッチする限り、繰り返し除去を行うことによって、さらに除去を進める。
そして、次に大事なのは、
サロゲートペアの残りカスの除去だ。
上記正規表現による除去では、除去しきれないのが、絵文字の厄介なところ。
4バイト以上の文字や、サロゲートペアの片割れが残る可能性がある。
(サロゲートペアとは、絵文字は二つ以上の文字コードを、一つの文字とすることによって表現されているものが大半。
そのペアのことを指す)
なので、4バイト以上の文字と、その片割れを含めない文字列を返すようにしている。
以上だ。
今回は、ブラウザ動作のJavaScriptでの実行だが、
他の言語・環境においても、応用が効くだろう。
さて、仕事戻ろうか・・・。
anonymous
| 2023年6月30日 20:25 | 返信
バグだらけで完璧じゃないですね・・・
taka
| 2023年7月10日 13:19 | 返信
質問ですが、encodeURIComponentの引数にvという値があるのですが、これはどこから出てきた値でしょうか
●みやびプリンからtakaへの返信
| 2023年8月 1日 20:06 | 返信
ご指摘ありがとうございます。
確かに、定義されてない変数ですね・・・。
確認して、記事を直します。
●みやびプリンからanonymousへの返信
| 2023年8月 1日 20:08 | 返信
コメントありがとうございます。
恐縮ですが、どこらへんにバグがありましたでしょうか・・・?
記事のコードと、実際動かして確認していたコードに差異があった可能性もありますので、
具体的に箇所をご指摘いただければ幸いです。
もちろん、自身でも再確認しますが。
●みやびプリンからanonymousへの返信
| 2023年8月 1日 23:43 | 返信
ご指摘ありがとうございました。
記載時に慌ててコードが間違ってしまっていたようです・・・。
修正しましたので、どうかよろしければお使いください。