JavaScriptで特殊文字を削除

JavaScriptで任意の文字列から特定の文字を削除する場合、普通はreplaceを使います。

var txtBefore = "abcde";
var txtAfter = txtBefore.replace(/c/g,"");

txtBeforeから'c'という文字を""(空白)に置換することで、削除を実現します。

/の後ろにあるgを付与することで、文字列から全ての指定文字を削除するモードになります。

 

今回は、これだと削除できない(と思う)特殊文字の削除についてです。

たとえば「ゼロ幅スペース」。

  は半角スペースではないというお話 (フェンリル | デベロッパーズブログ)

スペース無し あいうえお
ゼロ幅スペース あ​い​う​え​お
半角スペース あ い う え お

ゼロ幅スペースは、見た目上はスペース無しと同じですが、間には確かにスペース文字が存在します。

上記の3つの「あいうえお」をコピーして適当なテキストエディタにペーストしてもらえるとわかると思います。

このゼロ幅スペースは、ASCIIコードのUnicodeの「8203」で入力することができます。htmlに出力するには「​」(10進数)または「​」(16進数)と書きます。

 

また、たとえば「垂直タブ」。

xmlに垂直タブが含まれていて解析エラーになる件 - LET__IT__RIDE

垂直タブ  

これもブラウザによっては見た目で判別できず、しかしコピー&ペーストで間に特殊文字が出力されます。IEだと通常のスペースに変換されているかもしれませんが。

この垂直タブは、ASCIIコードの「11」で、html出力は「」(10進数)または「」(16進数)となります。

 

これらの特殊文字を削除するために、ASCIIコードを指定して削除するスクリプトを組んでみました。

var spStr = [
11, // 垂直タブ
8203 // ゼロ幅スペース
];

var txtBefore = document.getElementById("テキストエリアのID属性").value;
var txtAfter = "";
for (var i=0; i<txtBefore.length; i++) {
  var chr = txtBefore.charCodeAt(i);
  if (spStr.indexOf(chr) == -1) {
    txtAfter += String.fromCharCode(chr);
  }
}
document.getElementById("テキストエリアのID属性").value = txtAfter;

String.charCodeAt(n)でn番目の文字のASCIIコードを取得し、spStrで定義した特殊文字に該当するかをチェックします。

該当しなかった場合、String.fromCharCode(ASCIIcode)でASCIIコードから元の文字を指定し出力文字に連結します。

これで、spStrで定義した特殊文字だけがふるい落とされるようになります。

追記(2017/05/08)

2年近く前の記事への追記となってしまい恐縮ですが、単なるreplaceだけでも特殊文字削除ができたので補足しておきます。

var txt = document.getElementById("テキストエリアのID属性").value;
txt = txt.replace(/\u200B/g, "");  
document.getElementById("テキストエリアのID属性").value = txt;

まず、ゼロ幅スペースの「8203」はASCIIコードではなくUnicodeでした。ASCIIコードは制御文字を含めても128文字しかありませんので、8203とかあるわけないですね。

垂直タブの「11」は制御文字としてASCIIコードにも存在しますが、同時にUnicodeでも10進数で11です。

で、JavaScriptにはUnicodeエスケープという概念があるようです。

Lexical grammar - JavaScript | MDN

\uXXXX」という形で16進数のUnicodeを書くと、JavaScript内で特殊文字を扱うことができます。

前述のように、10進数の「8203」は16進数だと「200B」です。

なので、「\u200B」をreplaceに渡してあげればOKでした。