[JavaScript]\uXXXX形式にunicodeエスケープする関数
さっきはPerlにはまるとか言っておきながら結局JavaScript…
JavaScriptの文字列を、\uXXXXの形式のUnicodeEscapeSequenceにエスケープする関数を書きました。
JavaScriptの文字列をJSONとかでよく見かける、
\u672c\u65e5\u306f\u6674\u5929\u306a\u308a
の形式の文字列に変換する関数です。ソースやサンプルは続きで。
ソース
var unicodeEscape = function(str) {
var code, pref = {1: '\\u000', 2: '\\u00', 3: '\\u0', 4: '\\u'};
return str.replace(/\W/g, function(c) {
return pref[(code = c.charCodeAt(0).toString(16)).length] + code;
});
};
_0-9a-zA-Z以外の文字は全て\uXXXXの形式に変換されます。
何気にすごく重たい処理なので出来る限り軽いスクリプトになるように工夫しました。個人的には、prefオブジェクトを使ってpadding処理を簡略化した点が一番の工夫。
文字エンコーディングに依存しない形に変換したいときやJSON変換関数を書くときなんかには便利です。Firefoxではuneval()関数を使えば一発ですが…
サンプル
↓のボックスで試してみて下さい。
ここに結果が表示されます。
追記[2007-12-22]
エスケープ後のデータ量を節約したり、エスケープ後にURIエンコードして送信したりするのであれば、改行と引用符だけエスケープしてやればいいということに気づいた。(UnicodeEscapeSequenceに変換してからURIエンコードしたほうが、多くの場合データ量が小さくなるということがわかった。)
ということで、↓が新しく書いたソース
var escape = function(str) {
var lt = {'\n': 'n', '\r': 'r', '\u2028': 'u2028', '\u2029': 'u2029'};
return str.replace(/[\n\r\u2028\u2029\'\"\\]/g, function(c) { return '\\' + (lt[c] || c); });
};
行区切り文字と(単|二重)引用符とバックスラッシュだけエスケープしたもの。引用符でくくるだけで、JavaScriptの文字列リテラルとしてevalすることができます。
追記[2007-12-28]
実は、
{1: '\\u000', 2: '\\u00', 3: '\\u0', 4: '\\u'}
を、
{1: '\\x0', 2: '\\x', 3: '\\u0', 4: '\\u'}
にしたほうが、\0x00-\0xFFの範囲では容量の面で有利だということに気づいた。ということで書き直したのが↓。
var unicodeEscape = function(str) {
var code, pref = {1: '\\x0', 2: '\\x', 3: '\\u0', 4: '\\u'};
return str.replace(/\W/g, function(c) {
return pref[(code = c.charCodeAt(0).toString(16)).length] + code;
});
};
\xXXの記法はJavaScript的には妥当なもの。ただし、RFC 4627を見る限りではJSONの仕様ではないのかな?