正規表現によるHTML内部のコピー<正規表現<Javascript<木暮仁

スタートページJavascript正規表現の基礎

正規表現によるHTML内部のコピー

HTMLの内部にある選択個所の内容を同じHTML内部の表示場所にコピー表示することを対象にします。
正確にコピーするには、正規表現による加工が必要になります。それを順を追って説明します。
しかし、文章そのものではなく機能をコピーする場合には、その加工が機能を失うので注意が必要です。

・選択個所にタグが含まれないとき            → 例3
・タグが含まれ、機能ではなく記述内容を表示したいとき  → 例5
・タグが含まれ、記述内容ではなく機能をコピーしたいとき → 例1


選択個所A:タグ("<"や">")がない場合

このHTML内に次の記述があります。<div id="選択個所A">:~</div>の範囲がコピーされる元の個所です。

□は全角のスペース、_は半角のスペースです。

<div id="選択個所A">:
1行目です。
□□2行目です。
________3_____行_____目です。

5行目です(上の4行目は空行)。
</div>

例1A:基本機能

アは、選択個所をスクリプトに読み込む機能です。イは、スクリプトで作成した内容を表示場所に書き出す機能です。
赤枠の場所に、<div id="表示場所1A"></div> が記述されています。
[実行]により、例1('選択個所A', '表示場所1A'): が実行されます。

すなわち、次のスクリプトは、「選択個所A」を入力文に読み込み、「加工せずにそのまま」出力文として「表示場所1」に書き出す機能です。例1では正規表現は用いていません。

function 例1(選択個所, 表示場所) {
    var 入力文 = document.getElementById(選択個所).innerHTML;  // ア
    var 出力文 = 入力文;
    document.getElementById(表示場所).innerHTML = 出力文;      // イ
}
例1('選択個所A', '表示場所1A');

「加工せずにそのまま」のはずだったのに、複数行が改行せずに1行で出力されてしまいました。

例2A:改行

例1Aで1行になってしまったのは、WindowsとHTMLで改行の仕組みが異なるからです。
Windowsでは、改行が見えないコード(\n)になっていますが、HTMLでは、それが無視され、<br>タグで指定することになっているからです。

赤のように、\nを<br>に変換しました。

function 例2(選択個所, 表示場所) {
    var 入力文 = document.getElementById(選択個所).innerHTML;
    var 出力文 = 入力文;
    出力文 = 出力文.replace(/\n/g, "<br>");
    document.getElementById(表示場所).innerHTML = 出力文;
}
例2('選択個所A', '表示場所2A');

改行は解決しましたが、「3行目」の半角スペースが崩れています。

例3A:半角スペース

例2Aで、半角スペースが崩れたのはHTMLの仕様です。HTMLでは、「連続した半角スペースは一つの半角スペースとみなす。行頭など特定の個所での半角スペースは無視する」ことになっています。それを回避するには、半角スペースをその代替文字である "&nbsp" に変更する必要があります。

function 例3(選択個所, 表示場所) {
    var 入力文 = document.getElementById(選択個所).innerHTML;
    var 出力文 = 入力文;
    出力文 = 出力文.replace(/\n/g, "<br>");
    出力文 = 出力文.replace(/ /g, "&nbsp;");
    document.getElementById(表示場所).innerHTML = 出力文;
}
例3('選択個所A', '表示場所3A');

これで選択個所と全く同じものが表示されました。

タグ("<"や">")がない場合は例3を用います。


選択個所B:HTMLの通常(タグがある)の文の場合

次の文が「選択個所B」にあります。HTMLではこのように多様なタグが含まれています。

<h4>タグを含む場合</h4>
<p>この次に半角スペースがあります。1___2___3___4___5<br>
地の色<span style="color:blue">ここは青色になる</span>地の色に戻る。<br>
リンク:<a href="#例1A">例1Aへ戻る</a></p>

例1B:機能のコピー

例1Aで示した「例1」を用います。

function 例1(選択個所, 表示場所) {
    var 入力文 = document.getElementById(選択個所).innerHTML;  // ア
    var 出力文 = 入力文;
    document.getElementById(表示場所).innerHTML = 出力文;      // イ
}
例1('選択個所B', '表示場所1B'):

半角スペースが崩れていますが、選択個所Bもこれと同じに表示されているのですから、問題はありません。
「ここは青色になる」は正しく青色になっていますし、「例1Aへ戻る」をクリックすれば正しくジャンプします。

例2や例3では、<br>タグが選択個所とスクリプトでダブってしまうので、各行間に空白行ができてしまうので不適切です。

タグ機能も含めたコピーでは例1を用います。

例4B:タグも含めたコピー(不適切)

選択個所Bに記述した通り、すなわち上の青枠で示した通りの内容を表示させたいことがあります。
そのため、"<"と">"を "&lt;"と"&gt;" に置き換えてみました。

function 例4(選択個所, 表示場所) {
    var 入力文 = document.getElementById(選択個所).innerHTML;
    var 出力文 = 入力文;
    出力文 = 出力文.replace(/ /g, " ");
    出力文 = 出力文.replace(/</g, "&lt;");
    出力文 = 出力文.replace(/>/g, "&gt;");
    document.getElementById(表示場所).innerHTML = 出力文;
}
例4('選択個所B', '表示場所4B');

改行を除いてはうまくいっています。改行のために、出力文 = 出力文.replace(/\n/g, "<br>"): を加えてみても、上の表示に<br>が加わるだけで改行されません。

例5B:タグも含めたコピー

例4Bのジレンマは、入力文を各行に分解して、変換を行った後に、各行に<br>を加えて連結して出力文を組み立てることにより解決できます。

function 例5(選択個所, 表示場所) {
    var 入力文 = document.getElementById(選択個所).innerHTML;
    var 出力文 = "";
    var 行 = new Array();
    行 = 入力文.split("\n");
    for (var i=0; i<行.length; i++) {
        行[i] = 行[i].replace(/ /g, " ");
        行[i] = 行[i].replace(/</g, "&lt;"); 
        行[i] = 行[i].replace(/>/g, "&gt;");
        出力文 += 行[i] + "<br>";           // 改行の復活と連結
    }
    document.getElementById(表示場所).innerHTML = 出力文;
}
例5('選択個所B', '表示場所5B');

最終行に余計な<br>タグが含まれますが、本質的な欠点ではなので、このままにしておきます。

タグを単なる文字として解釈しているので、「ここは青色になる」や「例1Aへ戻る」などの機能は失われます。
例5は、各行について個別の変換をするときに重要になる方法です。

選択個所をタグも含めて表示するには例5を用います。


選択個所C:スクリプトを含む場合

次のように選択個所にスクリプトが含まれています。

<script>
function fugou(x) {
    if (x > 0) alert("正数");
    else alert("負数");
}
</script>
<button onClick="fugou(10)">実行</button>

この場合は、「選択個所B:HTMLの通常(タグがある)の文の場合」と同じになります。

例1C:機能のコピー

タグ機能も含めたコピーでは例1を用います。

function 例1(選択個所, 表示場所) {
    var 入力文 = document.getElementById(選択個所).innerHTML;
    var 出力文 = 入力文;
    document.getElementById(表示場所).innerHTML = 出力文;
}
例1('選択個所C', '表示場所1C'):

上の[実行]をクリックすると、fugou(x) が実行されてダイアログボックスに「正数」が表示されます。スクリプトの部分もコピーされていることがわかります。

例5C:タグも含めたコピー

選択個所の記述(上の青枠の内容)をそのまま表示します。例5を使います。
これは、プログラム解説のページ作成などに利用できましょう。

function 例5(選択個所, 表示場所) {
    var 入力文 = document.getElementById(選択個所).innerHTML;
    var 出力文 = "";
    var 行 = new Array();
    行 = 入力文.split("\n");
    for (var i=0; i<行.length; i++) {
        行[i] = 行[i].replace(/ /g, " ");
        行[i] = 行[i].replace(/</g, "&lt;"); 
        行[i] = 行[i].replace(/>/g, "&gt;");
        出力文 += 行[i] + "<br>";
    }
    document.getElementById(表示場所).innerHTML = 出力文;
}
例5('選択個所C', '表示場所5C');