簡易なHTML特殊文字変換機(通常文字 <=> 特殊文字)



※標準のエンコード文字は、「 」「<」「>」「&」「"」「'」「©」です

はじめに

HTML特殊文字を元の文字列に変換する処理です。「&#12290;」にやられました。JavaScriptの簡易な変換処理が見つからなかったので自作しました。

仕様

  • エンコード
    • 一般的な文字実体参照を変換します
      • 次のもののみ対応します(他は対象外です)
      • &nbsp;, &lt;, &gt;, &amp;, &quot;, &apos;, &copy;
      • 「 」, 「<」, 「>」, 「&」, 「"」, 「'」, 「©」
    • 追加で設定された文字を数値文字参照で変換します
  • デコード
    • HTML特殊文字変換を含む文字列を元の文字列に変換します
    • 数値文字参照を変換します
      • 「&#\d+;」みたいなの(例:「&#12290;」)
      • 「&#x[0-9A-Fa-f]+;」みたいなの(例:「&#x3002;」)
    • 一般的な文字実体参照を変換します
      • 次のもののみ対応します(他は対象外です)
      • &nbsp;, &lt;, &gt;, &amp;, &quot;, &apos;, &copy;
      • 「 」, 「<」, 「>」, 「&」, 「"」, 「'」, 「©」
    • 一般的でない文字実体参照は、変換できません
      • 一般的でない文字実体参照はそのまま出力します

※コード内のmapオブジェクトに未定義の文字実体参照を追加することで完全な変換機にできます
 特殊文字一覧表:HTMLで使える文字コードの変換と書き方の説明 - ウェブランサー
 HTML特殊文字コード表
※数値文字参照(%16進数コード)は、非対応
 decodeURIComponent()を使う

ソースコード

htmlsce.js// HTML特殊文字変換(通常文字 → 特殊文字)
var htmlsce = (function() {
  const map = {' ':'&nbsp;','<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;',"'":'&apos;','©':'&copy;'};
  return function(text, charset) {
    charset = charset && charset.replace(/([\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F])/g, '\\$&') || '';
    return text.replace(new RegExp('[ <>&"\'©'+charset+']', 'g'), function(match) {
      if (map.hasOwnProperty(match)) {
        return map[match];
      } else {
        return '&#'+match.charCodeAt(match)+';';
      }
    });
  };
})();

htmlscd.js// HTML特殊文字変換(特殊文字 → 通常文字)
var htmlscd = (function() {
  const re = /&#x([0-9A-Fa-f]+);|&#(\d+);|&\w+;/g;
  const map = {'&nbsp;':' ','&lt;':'<','&gt;':'>','&amp;':'&','&quot;':'"','&apos;':"'",'&copy;':'©'};
  return function(text) {
    return text.replace(re, function(match, p1, p2) {
      if (match.charAt(1) == '#') {
        // 数値文字参照
        if (match.charAt(2) == 'x') {
          return String.fromCharCode(parseInt(p1, 16));
        } else {
          return String.fromCharCode(p2-0);
        }
      } else if (map.hasOwnProperty(match)) {
        // 定義済み文字実体参照
        return map[match];
      }
      return match;
    });
  };
})();

htmlscd.js// HTML特殊文字変換(特殊文字 → 通常文字)
var htmlscd = (function() {
  const map = {'&nbsp;':' ','&lt;':'<','&gt;':'>','&amp;':'&','&quot;':'"','&apos;':"'",'&copy;':'©'};
  return function(src) {
    const re = /&#x([0-9A-Fa-f]+);|&#(\d+);|&\w+;|[^&]+|&/g;
    let text = '';
    let m;
    while ((m=re.exec(src)) !== null) {
      if (m[0].charAt(0) == '&') {
        if (m[0].length == 1) {
          // ???
          text = text + m[0];
        } else if (m[0].charAt(1) == '#') {
          // 数値文字参照
          if (m[0].charAt(2) == 'x') {
            text = text + String.fromCharCode(parseInt(m[1], 16));
          } else {
            text = text + String.fromCharCode(m[2]-0);
          }
        } else if (map.hasOwnProperty(m[0])) {
          // 定義済み文字実体参照
          text = text + map[m[0]];
        } else {
          // 未定義文字実体参照(諦める)
          text = text + m[0];
        }
      } else {
        // 通常文字列
        text = text + m[0];
      }
    }
    return text;
  };
})();

htmlsce.jsは、"HTML special character encoder"の略称です。
htmlscd.jsは、"HTML special character decoder"の略称です。

使用例

var src = '"Hello World"テスト中です。<html></html>';
var enc = htmlsce(src, '。');
var dec = htmlscd(enc);
console.log(src);  // "Hello World"テスト中です。<html></html>
console.log(enc);  // &quot;Hello&nbsp;World&quot;テスト中です&#12290;&lt;html&gt;&lt;/html&gt;
console.log(dec);  // "Hello World"テスト中です。<html></html>

var src = '&quot;Hello World&quot;テスト中です&#12290;&#x3002;&lt;html&gt;&lt;&#47;html&gt;';
var dst = htmlscd(src);
console.log(dst);  // "Hello World"テスト中です。。<html></html>

コメント