HTML特殊文字変換

HTML 特殊文字を変換するツールのサンプルです。

JavaScript の正規表現を使って HTML 特殊文字(< >& ' ")をそれぞれ &lt; &gt; &amp; &#39; &quot; に変換します。

コードも掲載しているので、コピーしてローカルに保存して利用することもできます。

作成日:2019年05月10日

変換ツール

HTML ソース(変換するコード)を入力

変換結果


        

変換ツールのコード

以下は上記ツールの HTML と CSS です(ボタンのスタイルは Bootstrap を使用しています)。

HTML
<div id="entity_convertor">
  <h3>変換ツール</h3>
  <p>HTML ソースを入力</p>
  <div>
    <textarea id="input" rows="20" cols="60"></textarea>
  </div>
  <button id="convert" class="btn btn-primary">変換</button>
  <button id="copy" class="btn btn-primary">結果をコピー</button>
  <button id="clear_all" class="btn btn-danger">全てクリア</button>
  <button id="clear_html" class="btn btn-warning">HTML をクリア</button>
  <button id="clear_escape" class="btn btn-warning">出力をクリア</button>
  <button id="restore" class="btn btn-success">リストア</button>
  <div>
    <pre id="escapeHTML"></pre>
  </div>
</div>
CSS
textarea {
  width: 95%;
  margin: 10px auto;
}
#escapeHTML {
  width: 95%;
  border: 1px solid #ccc;
  padding: 10px;
  background-color: #efefef;
  font-family: "Lucida Console", Monaco, monospace;
  white-space: pre-wrap;
  overflow: auto;
  margin: 30px 0;
}

以下は上記ツールの JavaScript(jQuery)の記述です。コピーの処理は Vanilla JavaScript と同じなので省略しています。

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script>
jQuery(function($){

  var restore_input = '';
  var restore_escape = '';

  $('#convert').click(function() {
    restore_input = $('#input').val();
    var converted = $('#input').val().replace(/&/g,"&amp;")
    .replace(/"/g,"&quot;")
    .replace(/'/g,"&#39;")
    .replace(/</g,"&lt;")
    .replace(/>/g,"&gt;");
    restore_escape = 	converted;
    $('#escapeHTML').text(converted);
  });

  $('#clear_html').click(function() {
    $('#input').val('');
  });

  $('#clear_escape').click(function() {
    $('#escapeHTML').text('');
  });

  $('#clear_all').click(function() {
    $('#input').val('');
    $('#escapeHTML').text('');
  });

  $('#restore').click(function() {
    $('#input').val(restore_input);
    $('#escapeHTML').text(restore_escape);
  });

});
</script>
JavaScript

以下は jQuery を使わない場合(Vanilla JavaScript/素のJavaScript)の例です。

コピー(クリップボードへの書き込み)は Clipboard API のインターフェース Clipboard のメソッド Clipboard.writeText() を使用しているので、IE など古いブラウザには対応していません。

<script>
  const convertBtn = document.getElementById('convert');
  const clearAllBtn = document.getElementById('clear_all');
  const clearHtmlBtn = document.getElementById('clear_html');
  const clearEscapeBtn = document.getElementById('clear_escape');
  const restoreBtn = document.getElementById('restore');
  const input =  document.getElementById('input');
  const escapeHTML =  document.getElementById('escapeHTML');
  const copyBtn = document.getElementById('copy');
  let inputValue = '';
  let escapeHTMLValue = '';

  convertBtn.addEventListener('click', () => {
    inputValue = input.value;
    escapeHTMLValue = inputValue.replace(/&/g,"&amp;")
    .replace(/"/g,"&quot;")
    .replace(/'/g,"&#39;")
    .replace(/</g,"&lt;")
    .replace(/>/g,"&gt;");
    escapeHTML.textContent = escapeHTMLValue;
  });

  clearAllBtn.addEventListener('click', () => {
    escapeHTML.textContent = '';
    input.value = '';
  });

  clearHtmlBtn.addEventListener('click', () => {
    input.value = '';
  });

  clearEscapeBtn.addEventListener('click', () => {
    escapeHTML.textContent = '';
  });

  restoreBtn.addEventListener('click', () => {
    escapeHTML.textContent = escapeHTMLValue;
    input.value = inputValue;
  });

  copyBtn.addEventListener('click', () => {
    // コピー処理の関数を呼び出してテキストコンテンツを渡す
    copyToClipboard(copyBtn, escapeHTML.textContent)
  }, false);

  // コピー処理の定義
  function copyToClipboard(btn, text) {
    // Clipboard API に対応していないブラウザ
    if (!navigator.clipboard) {
      alert('お使いのブラウザではコピーできません。');
    }
    // Clipboard API の writeText 関数でクリップボードに text をコピー
    navigator.clipboard.writeText(text).then(
      // 成功時の処理
      () => {
        btn.textContent = 'コピー完了';
        resetCopyBtnText(btn, 1500);
      },
      // 失敗時の処理
      (error) => {
        btn.textContent = '失敗';
        resetCopyBtnText(btn, 1500);
        console.log(error.message);
      }
    );
  };

  // ボタンのテキスト(ラベル)を指定されたミリ秒後にリセットする関数
  function resetCopyBtnText(btn, delay) {
    setTimeout(() => {
      btn.textContent = '結果をコピー'
    }, delay)
  }
</script> 
replace() の第2引数に関数を指定

上記のコードでは、特殊文字の変換(15〜19行目)を replace() メソッドをチェーンして使用していますが、replace() メソッドの第2引数に関数を指定して以下のように記述することもできます。

replace() メソッドの第2引数の関数は、第1引数にマッチした部分文字列(match)を受け取ります。以下では specialChars という特殊文字をキーに、エスケープ後の文字列を値に持つオブジェクトを用意して、特殊文字を変換しています。

specialChars のオブジェクトのキー(プロパティ名)は、特殊文字なので値にアクセスするには [] を使います(ドット演算子 . ではアクセスできません)。

escapeHTMLValue = inputValue.replace(/[<>&'"]/g, (match) => {
  const specialChars = {
    '<': '&lt;',
    '>': '&gt;',
    '&': '&amp;',
    "'": '&#39;',
    '"': '&quot;'
  };
  return specialChars[match];
});

この方法の場合、1回の正規表現で一括置換を行うので、マッチするパターンが多くなる場合でも、1回の処理で済むため効率的です。

MDN :String.prototype.replace()

関連ページ:

サンプル

以下のコードをコピーして、.html ファイルとして保存すれば、ローカルで使用できます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HTML特殊文字変換ツール</title>
  <style>
    #entity_convertor {
      max-width: 960px;
      margin: 50px auto;
    }

    textarea {
      width: 95%;
      margin: 10px auto;
    }

    button {
      margin-right: 10px;
    }

    #escapeHTML {
      width: 95%;
      border: 1px solid #ccc;
      padding: 10px;
      border-radius: 0px;
      background-color: #efefef;
      font-family: "Lucida Console", Monaco, monospace;
      white-space: pre-wrap;
      overflow: auto;
      margin: 30px 0;
    }

    #clear_all,
    #clear_escape {
      margin-right: 0 30px;
    }

    #escapeHTML {
      font-size: 13px;
      font-family: "Lucida Console", Monaco, monospace;
      min-height: 50px;
    }
  </style>
</head>
<body>
  <div id="entity_convertor">
    <h3>変換ツール</h3>
    <p>HTML ソース(変換するコード)を入力</p>
    <div>
      <textarea id="input" rows="20" cols="80"></textarea>
    </div>
    <button id="convert" class="btn btn-primary">変換</button>
    <button id="copy" class="btn btn-primary">結果をコピー</button>
    <button id="clear_all" class="btn btn-danger">全てクリア</button>
    <button id="clear_html" class="btn btn-warning">HTML をクリア</button>
    <button id="clear_escape" class="btn btn-warning">出力をクリア</button>
    <button id="restore" class="btn btn-success">リストア</button>
    <div class="output">
      <h4>変換結果</h4>
      <pre id="escapeHTML"></pre>
    </div>
  </div>

  <script>
    const convertBtn = document.getElementById('convert');
    const clearAllBtn = document.getElementById('clear_all');
    const clearHtmlBtn = document.getElementById('clear_html');
    const clearEscapeBtn = document.getElementById('clear_escape');
    const restoreBtn = document.getElementById('restore');
    const input = document.getElementById('input');
    const escapeHTML = document.getElementById('escapeHTML');
    const copyBtn = document.getElementById('copy');
    let inputValue = '';
    let escapeHTMLValue = '';
    convertBtn.addEventListener('click', () => {
      inputValue = input.value;
      escapeHTMLValue = inputValue.replace(/[<>&'"]/g, (match) => {
        const specialChars = {
          '<': '&lt;',
          '>': '&gt;',
          '&': '&amp;',
          "'": '&#39;',
          '"': '&quot;'
        };
        return specialChars[match];
      });
      escapeHTML.textContent = escapeHTMLValue;
    });
    clearAllBtn.addEventListener('click', () => {
      escapeHTML.textContent = '';
      input.value = '';
    });
    clearHtmlBtn.addEventListener('click', () => {
      input.value = '';
    });
    clearEscapeBtn.addEventListener('click', () => {
      escapeHTML.textContent = '';
    });
    restoreBtn.addEventListener('click', () => {
      escapeHTML.textContent = escapeHTMLValue;
      input.value = inputValue;
    });
    copyBtn.addEventListener('click', () => {
      copyToClipboard(copyBtn, escapeHTML.textContent)
    }, false);

    function copyToClipboard(btn, text) {
      if (!navigator.clipboard) {
        alert('お使いのブラウザではコピーできません。');
      }
      navigator.clipboard.writeText(text).then(
        () => {
          btn.textContent = 'コピー完了';
          if(text.trim() === '') btn.textContent = 'コピーは空です';
          resetCopyBtnText(btn, 1500);
        },
        (error) => {
          btn.textContent = '失敗';
          resetCopyBtnText(btn, 1500);
          console.log(error.message);
        }
      );
    };

    function resetCopyBtnText(btn, delay) {
      setTimeout(() => {
        btn.textContent = '結果をコピー'
      }, delay)
    }
  </script>
</body>
</html>