【Blogger】画像コードを置換するための正規表現集

Blogger の編集画面から投稿やページに画像を挿入すると、画像コードが以下のような img 要素が div.separatora 要素に囲まれた形で出力されます(画像 URL の一部を省略済み)。

<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/.../.../s1200/image.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="630" data-original-width="1200" height="168" src="https://blogger.googleusercontent.com/img/b/.../.../s320/image.png" width="320" /></a></div>

もちろんこのコードをそのまま使ってもいいのですが、個人的にはシンプルなコードが好きなので、手作業で不要な要素や属性を削除して使っていました。

ただ、挿入する画像が多くなると手作業にも限界があります。幸い Blogger の投稿画面には置換機能があるので、正規表現を使えば画像コードの一括置換が行えそうです。

そこで本記事では、Blogger において画像コードの置換に使えそうな正規表現をまとめてみました。

アイキャッチ
この記事の目次

Blogger における正規表現の使用方法

Blogger の投稿・ページの編集画面において、次項より紹介する正規表現を用いた画像コードの置換方法を説明します。

まず、投稿・ページの編集画面でいつも通り画像をアップロードし、投稿に画像コードを挿入します。この操作は HTML ビュー と 作成ビューどちらで行っても大丈夫ですが、画像挿入後はなるべく画像コードに触らないようにしてください。

作成ビューをお使いの方は HTML ビューに変更し、エディタの右上に表示されている「置換」ボタンをクリックします。

Blogger の投稿・ページの編集画面の「置換」ボタン

「Replace:」に正規表現(検索文字列)を両端のスラッシュ込みで入力し、Enter を押します。

Blogger の投稿・ページの編集画面の置換ツールの検索文字列入力欄

「With:」に置換文字列を入力し、Enter を押します。

Blogger の投稿・ページの編集画面の置換ツールの置換文字列入力欄

「Yes」(選択された文字列を置換する)、「No」(選択された文字列を置換しない)、「All」(一括置換)、「Stop」(検索終了)のボタンが表示されるので、「Yes」か「All」をクリックすると画像コードが置換されます。

Blogger の投稿・ページの編集画面の置換ツールの検索ボタン。右から「Yes」、「No」、「All」、「Stop」のボタンがある

この記事で紹介する正規表現がどのように機能するのか確認できるツールを用意しました。以下のページ内リンクからツールに飛べます💁

要素を削除・追加する正規表現

画像コード内の HTML 要素を削除、追加するための正規表現集です。

本記事の冒頭で挙げたような、div.separator で囲まれた画像コードを対象としています。

画像を一括で挿入したときに画像コード間に改行がないのが気になったので、置換文字列の末尾に \n を付けて改行するようにしています。いらない方はこの部分を削除してください。

また、作成ビューで画像を挿入した場合デフォルトの状態だと alt 属性がないので、適宜追加してください。

div を削除

いちばん外側の div.separator を削除します。a 要素はそのままなので、Blogger 標準のライトボックスは動作します。

/<div class=["']separator["'].+?>(<a.+?><img.+?\/><\/a>)<\/div>/
$1\n

a を削除

a 要素を削除します。この場合、Blogger 標準のライトボックスは動作しません。

/(<div class=["']separator["'].+?>)<a.+?>(<img.+?\/>)<\/a>(<\/div>)/
$1$2$3\n

div と a を削除

div.separatora 要素を削除し、内側のimg 要素のみを残します。こちらも、Blogger 標準のライトボックスは動作しません。

/<div class=["']separator["'].+?><a.+?>(<img.+?\/>)<\/a><\/div>/
$1\n

figure と figcaption を追加(キャプション付き画像)

div.separatora 要素を削除し、新たにfigure 要素と figcaption 要素を追加します。画像にキャプション(説明)を付けたいときにおすすめです。

/<div class=["']separator["'].+?><a.+?>(<img.+?\/>)<\/a><\/div>/
<figure>\n  $1\n  <figcaption>キャプション</figcaption>\n</figure>\n

picture と source を追加(WebP 対応)

div.separatora 要素を削除し、新たにpicture 要素と source 要素を追加します。

/<div class=["']separator["'].+?><a.+?><img\s(.*?)src=["'](.+?\/[swh]\d{1,4}.*?)(\/.+?)["']\s*(.*?)\s*\/><\/a><\/div>/
<picture>\n  <source srcset="$2-rw-e365$3" type="image/webp"/>\n  <img loading="lazy" $1 src="$2-e365$3" $4/>\n</picture>\n

source 要素の srcset 属性に WebP 化とキャッシュの有効期限の変更を行った URL を埋め込んでいます。また、img タグでも画像 URL に対してキャッシュの有効期限の変更を行い、遅延読み込みのコード loading="lazy" を追加しました。

WebP 変換の画像パラメータ -rw については、以下の記事で解説されています。

キャッシュの有効期限を変更する画像パラメータ -e** は任意の数字)については、以下の記事で解説しています。

figure, figcaption, picture, source を追加(キャプション付き画像 + WebP 対応)

前述の「figure と figcaption を追加」と「picture と source を追加」の合わせ技です。

/<div class=["']separator["'].+?><a.+?><img\s(.*?)src=["'](.+?\/[swh]\d{1,4}.*?)(\/.+?)["']\s*(.*?)\s*\/><\/a><\/div>/
<figure>\n  <picture>\n    <source srcset="$2-rw-e365$3" type="image/webp"/>\n    <img loading="lazy" $1 src="$2-e365$3" $4/>\n  </picture>\n  <figcaption>キャプション</figcaption>\n</figure>\n

属性を削除する正規表現

HTML 要素内の属性を削除するための正規表現集です。置換文字列はなにも入力しないでください。

こちらの正規表現は画像コード以外の部分も変換されるおそれがあるため(筆者の正規表現偏差値が低いせいですすみません)、一括置換ではなく様子を見ながらの置換をおすすめします。

div の style を削除

div.separatorstyle 属性を削除します。

/(?<=<div class=["']separator["'])\sstyle=["'].*?["'](?=.*?>)/

Blogger の標準 CSS に div.separator への指定箇所があるので、とりあえず class 属性は残して style 属性だけを消してみました。

a の style と imageanchor を削除

astyle 属性と、作成モードで画像を挿入したときのみ付与される imageanchor 属性を削除します。

/(?<=<a\s.*?)\s(style|imageanchor)=["'].+?["'](?=.*?>)/

この imageanchor 属性、調べてもどういう用途で使われているのかいまいちわからないんですが(どうやら画像の表示位置を示すっぽい?)、Nu Html Checker に掛けると以下のようなエラーが出るので消しても大丈夫だと思います。

Attribute imageanchor not allowed on element a at this point.

(和訳:現時点では、a 要素では imageanchor 属性を使用できません。)

ちなみに imageanchor 属性だけを消したい場合は、上記の検索文字列の (style|imageanchor) の部分を imageanchor に書き換えればオッケーです。

img の border と data-original-width/height を削除

imgborder 属性と、data-original-width 属性および data-original-height 属性を削除します。

/(?<=<img.*?)\s(border|data-original-(width|height))=["'].+?["'](?=.*?\/>)/

border 属性は Nu Html Checker に掛けると以下のように警告が出るように、すでに廃止されている属性なので削除推奨です。

The border attribute is obsolete. Consider specifying img { border: 0; } in CSS instead.

(和訳:border 属性は廃止されました。代わりに CSS で img { border: 0; } を指定することを検討してください。)

data-original-width 属性と data-original-height 属性に関しては、以下のスレッドによると「特にレスポンシブ画像を生成する際に、Blogger の内部システムが画像のオリジナルサイズを把握するために使われる」そうです。

画像表示の最適化に一役買ってるなら残しておいてもいいのかなと思いますが、筆者はなるべくコードを短くしたい人間なので容赦なく消します笑

ちなみに border 属性だけを消したい場合は、上記の検索文字列の (border|data-original-(width|height)) の部分を border に書き換えればオッケーです。

画像コード用正規表現確認ツール

ここまで紹介してきた正規表現で画像コードがどのように置換されるのか確認できるツールを作りました。コピー機能が付いているので、画像コード変換ツールとしても使えます🙆

「変換前のコード」のテキストエリアに画像コードを貼り付け(デフォルトでダミーコードを入力してあります)、置換オプションを選択後、「変換」ボタンをクリックしてください。「変換後のコード」のテキストエリアに、正規表現で置換された画像コードが出力されます。

選択したオプションを解除したい場合は、「選択解除」ボタンをクリックしてください。

「コードをコピー」ボタンで置換後のコードがコピーできます。コピー機能に Clipboard API を利用しているため、Internet Explorer には非対応です。IE をお使いの方はコードを全選択してコピーしてください。

「元に戻す」ボタンをクリックすると、「変換前のコード」のテキストエリアはダミーコードが入力された状態に、「変換後のコード」のテキストエリアは空になります。間違えて押さないようにお気を付けください。

以下が、確認ツールの HTML と JavaScript です。CSS は当ブログ独自仕様すぎて参考にならないと思うので割愛しています。

<form class="replace-tool">
  <label>変換前のコード:<br><textarea id="inputCode" placeholder="ここに画像コードを入力"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/.../.../s1200/image.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="630" data-original-width="1200" height="168" src="https://blogger.googleusercontent.com/img/b/.../.../s320/image.png" width="320" /></a></div></textarea></label>
  <label>変換後のコード:<br><textarea id="outputCode" placeholder="変換されたコードがここに表示されます"></textarea></label>

  <div class="replace-menu" data-title="要素を削除・追加">
    <label><input type="radio" name="tag" value="option1"/> div を削除</label>
    <label><input type="radio" name="tag" value="option2"/> a を削除</label>
    <label><input type="radio" name="tag" value="option3"/> div と a を削除</label>
    <label><input type="radio" name="tag" value="option4"/> picture と source を追加</label>
    <label><input type="radio" name="tag" value="option5"/> figure と figcaption を追加</label>
    <label><input type="radio" name="tag" value="option6"/> figure, figcaption, picture, source を追加</label>
  </div>

  <div class="replace-menu" data-title="属性を削除">
    <label><input type="checkbox" name="attr" value="option1"/> div の style を削除</label>
    <label><input type="checkbox" name="attr" value="option2"/> a の style と imageanchor を削除</label>
    <label><input type="checkbox" name="attr" value="option3"/> img の border と data-original-width/height を削除</label>
  </div>

  <button type="button" onclick="replaceCode()">変換</button>
  <button type="button" onclick="deselectOptions()">選択解除</button>
  <button type="button" onclick="copyReplacedCode()">コードをコピー</button>
  <button type="reset">元に戻す</button>
</form>

<script> 
function replaceCode() {
  const inputArea = document.querySelector('.replace-tool  #inputCode');
  const outputArea = document.querySelector('.replace-tool  #outputCode');
  let outputCode = inputArea.value;

  const selectedTag = document.querySelector('.replace-tool input[name="tag"]:checked');

  if (selectedTag) {
    switch (selectedTag.value) {
      case 'option1':
        outputCode = outputCode.replace(/<div class=["']separator["'].+?>(<a.+?><img.+?\/><\/a>)<\/div>/g, '$1\n');
        break;
      case 'option2':
        outputCode = outputCode.replace(/(<div class=["']separator["'].+?>)<a.+?>(<img.+?\/>)<\/a>(<\/div>)/g, '$1$2$3\n');
        break;
      case 'option3':
        outputCode = outputCode.replace(/<div class=["']separator["'].+?><a.+?>(<img.+?\/>)<\/a><\/div>/g, '$1\n');
        break;
      case 'option4':
        outputCode = outputCode.replace(/<div class=["']separator["'].+?><a.+?><img\s(.*?)src=["'](.+?\/[swh]\d{1,4}.*?)(\/.+?)["']\s*(.*?)\s*\/><\/a><\/div>/g, '<picture>\n  <source srcset="$2-rw-e365$3" type="image/webp"/>\n  <img loading="lazy" $1 src="$2-e365$3" $4/>\n</picture>\n');
        break;
      case 'option5':
        outputCode = outputCode.replace(/<div class=["']separator["'].+?><a.+?>(<img.+?\/>)<\/a><\/div>/g, '<figure>\n  $1\n  <figcaption>キャプション</figcaption>\n</figure>\n');
        break;
      case 'option6':
        outputCode = outputCode.replace(/<div class=["']separator["'].+?><a.+?><img\s(.*?)src=["'](.+?\/[swh]\d{1,4}.*?)(\/.+?)["']\s*(.*?)\s*\/><\/a><\/div>/g, '<figure>\n  <picture>\n    <source srcset="$2-rw-e365$3" type="image/webp"/>\n    <img loading="lazy" $1 src="$2-e365$3" $4/>\n  </picture>\n  <figcaption>キャプション</figcaption>\n</figure>\n');
        break;
    }
  }

  const selectedAttr = document.querySelectorAll('.replace-tool input[name="attr"]:checked');

  selectedAttr.forEach(a => {
    switch (a.value) {
      case 'option1':
        outputCode = outputCode.replace(/(?<=<div class=["']separator["'])\sstyle=["'].*?["'](?=.*?>)/g, '');
        break;
      case 'option2':
        outputCode = outputCode.replace(/(?<=<a\s.*?)\s(style|imageanchor)=["'].+?["'](?=.*?>)/g, '');
        break;
      case 'option3':
        outputCode = outputCode.replace(/(?<=<img.*?)\s(border|data-original-(width|height))=["'].+?["'](?=.*?\/>)/g, '');
        break;
    }
  })

  outputArea.value = outputCode
}

function deselectOptions() {
  document.querySelectorAll('.replace-tool input[name]:checked').forEach(c => {
    c.checked = false
  })  
}

function copyReplacedCode() {
  const outputCode = document.querySelector('.replace-tool #outputCode').value;
  
  navigator.clipboard.writeCode(outputCode).then(() => {
    alert('コピーしました')
  }).catch(() => {
    alert('コピーに失敗しました')
  })
}
</script>

ChatGPT に作ってもらったコードにいろいろと手を加えてみました。switch 文が使われてる部分は、自力でコード書いたら十中八九 if 文にしてしまうと思うので勉強になりました。

あとがき

Blogger のデフォルトの画像コードに使える正規表現をまとめました。置換後のコードの確認用に画像コード変換ツールも作ってみました。

前述の通り正規表現がだいぶ苦手なもので、もしかしたら掲載している文字列に間違いがあるかもしれません。その場合は本記事のコメント欄で教えていただけると助かります。

画像コード置換関連で、他にもいい感じの正規表現を考えついたら随時追加していこうと思います。

編集
ホーム