PPP's Blog

雑コード帳

正規表現で、相対パスの値を保持したまま置換する

やりたいこと

ウェブサイト全体を対象にした置換作業をおこないたい。 要望としては、HTMLに含まれる、相対パス指定はそのまま保持されていてほしい。それを正規表現による置換で実現する。

ウェブサイトの構成は以下のようになっている。 異なる階層に、HTMLがそれぞれ1つずつ入っている。

index.html
about/index.html
products/detail/index.html

階層が異なるので、相対パス指定箇所はそれぞれのファイルで値が異なっている。

実行環境

検索で引っ掛けたい文字列

div#footerの範囲のHTMLを引っ掛けたい。

<div id="footer"></div>

このdivの中には、aタグとimgタグが交互に3回ずつ登場する。

実際に検索する文字列

検索対象は、3ファイルで、それぞれ以下のようになっている。

ルートディレクトリ直下のindex.html

<div id="footer">
      <p>
        <a href="notice.htm"><img src="images/notice.gif" alt="お知らせ"></a><a href="privacy_policy.htm"><img src="images/privacy_policy.gif" alt="プライバシー・ポリシー"></a><a href="link.htm"><img src="images/link.gif" alt="関連リンク"></a>
      </p>
      <address>
        Copyright(C) Lorem Ipsim &amp; Logistics, Ltd. All Rights Reserved
      </address>
      <!-- end #footer -->
    </div>

aboutフォルダ内のindex.html

<div id="footer">
    <p>
        <a href="../notice.htm"><img src="../images/notice.gif" alt="お知らせ"></a><a href="../privacy_policy.htm"><img
                src="../images/privacy_policy.gif" alt="プライバシー・ポリシー"></a><a href="../link.htm"><img src="../images/link.gif"
                alt="関連リンク"></a>
    </p>
    <address>
        Copyright(C) Lorem Ipsim &amp; Logistics, Ltd. All Rights Reserved
    </address>
    <!-- end #footer -->
</div>

products/detailフォルダ内のindex.html

<div id="footer">
    <p>
        <a href="../../notice.htm"><img src="../../images/notice.gif" alt="お知らせ"></a><a href="../../privacy_policy.htm"><img src="../../images/privacy_policy.gif" alt="プライバシー・ポリシー"></a><a href="../../link.htm"><img src="../../images/link.gif" alt="関連リンク"></a>
    </p>
    <address>Copyright(C) Lorem Ipsim &amp; Logistics, Ltd. All Rights Reserved</address>
    <!-- end #footer -->
</div>

実際に正規表現を書く

改めて、今回やりたいことを列挙する。

  • div#footerの範囲を対象にしたい
  • 範囲内に存在する相対パス指定は、そのまま維持して置換したい

実際に書いた正規表現

検索スペースに、下記正規表現を記入。

<div id="footer">[\s\S\n]+?href="(.*?)"[\s\S\n]+?src="(.*?)"[\s\S\n]+?href="(.*?)"[\s\S\n]+?src="(.*?)"[\s\S\n]+?href="(.*?)"[\s\S\n]+?src="(.*?)"[\s\S\n]+?<\/div>

置換スペースに、下記内容を入力して、実際にVSCode上で確認する。

1: $1\n2: $2\n3: $3\n4: $4\n5: $5\n6: $6

一番右側のスペースに、置換結果のプレビューが表示されている。 f:id:code-zen:20220224233418p:plain f:id:code-zen:20220224233440p:plain f:id:code-zen:20220224233458p:plain

相対パス指定された値がちゃんと保持されているのが確認できた。

相対パスの値を保持してくれた部分の説明

先ほど載せたものを重複を外して再掲載する。
<div id="footer">[\s\S\n]+?href="(.*?)"[\s\S\n]+?src="(.*?)"[\s\S\n]+?<\/div>

相対パスの値を保持するのに役立ったのは、(.*?)である。これはキャプチャグループと呼ばれていて、()の中に書いた正規表現でマッチした値を、置換の際に利用することができる。

VSCodeでキャプチャした値を置換に使う際には、$1を置換スペースに記述する必要がある。キャプチャグループを複数使った場合は、その個数だけ$の後の数字を増やすだけで良い。

参考