Mmemo

PC作業に関するメモ

[JS]HTML文字列の一部を置換する際に対象からタグ部分を除外する方法

「[JS]リアルタイムにページ内検索をしてハイライト表示する」のようにHTML文字列の一部を動的に置換したい時のお話。

例えば以下のようなHTMLがあったとする。

<div id="box">
  <p>sample文章があります。</p>
  <p>sampleという文字だけ<span class="sample">太字</span>にしてみましょう。</p>
</div>

この文章中のsampleのみを太字にしたいと考え、以下のようにsampleという文字列をspanタグで囲む処理を行う。

document.getElementById('box').innerHTML
= document.getElementById('box').innerHTML.replace(/sample/g, `<span class="bold">sample</span>`);

すると当然「class=”sample”」の部分も置換され、望んだ結果を得ることが出来ない。
コンテンツのみを対象としてHTML文字列の置換を行う際には以下のようにすると上手くいく。

//正規表現オブジェクト1を生成する。これにより「>」~「<」でsampleという文字列を含む部分がマッチする。
const regexp1 = new RegExp(`(?<=>)[^<>]*?(sample)[^<>]*?(?=<)`,'gi');
//正規表現オブジェクト2を生成する。2からさらにsampleという文字列がマッチする。
const regexp2 = new RegExp('sample','gi');
//id="box"の子要素にforEach
const box = document.getElementById('box');
box.innerHTML = box.innerHTML.replace(regexp1,function(){
  //arguments[0]はsampleを含むテキストノード、arguments[1]はマッチした文字列の()内※今回だとsample
  return arguments[0].replace(regexp2,`<span class="bold">${arguments[1]}</span>`);
});

結果

sample文章があります。

sampleという文字だけ太字にしてみましょう。