`.*?`が短く効きすぎて、ヘッダーを壊した

ナビゲーションのドロップダウンを整理するスクリプトを流した。
数分後、サイト全体のヘッダーが崩れているという報告が来た。

手取りを増やそう!をつくる第8回 / 全12回目次

グローバルナビのドロップダウンに項目が増えすぎていたので、整理するスクリプトを書いた。
対象のリンクを正規表現で拾って、要らない行を削る。よくある作業のつもりだった。

スクリプトを流して、反映を確認して、次の作業に移った。
そのすぐ後で、崩れたヘッダーのスクリーンショットが届いた。

最短マッチが、途中で止まっていた

使っていた正規表現は .*?。「最初に見つかった閉じタグまで」を拾うつもりで、非貪欲マッチにしていた。
ところがドロップダウンの中には

  • が何個も入れ子になっている。最短マッチは、いちばん内側の最初の
  • で止まっていた。

    削除の対象がそこで切れるので、残りの

  • と、外側を閉じるはずだった
  • が宙に浮く。
    その浮いた断片が、横一列にべたっと表示されていた。

    まず戻す。直すのはそのあと

    崩れていると分かった時点で、原因を調べるより先に本番を --restore で直前の状態に戻した。
    見えている画面を早く直したほうがいい。原因究明はローカルでいくらでもできる。

    正規表現を .*?\s* に直して、入れ子の外側までまとめて拾うようにした。
    それだけでは信用できなかったので、開きタグと閉じタグの数を機械的に数えて、差が0になっているかを確認してから、もう一度本番に反映した。

    「5項目ある」だけを見ていた

    反省しているのは、最初の確認のやり方だ。
    直したあと私は、ドロップダウンの先頭を開いて「5項目ちゃんと並んでいる」ことだけを見て、大丈夫だと判断していた。

    実際には、その5項目の下に浮いた断片がまだ残っていた。
    一部分だけ見て安心するのは、崩したときの正規表現とやっていることが同じだ。狭い範囲だけ見て、外側まで正しいと思い込む。

    それ以来、ナビゲーションのようなサイト全体に影響する変更は、変更箇所だけでなく前後のタグの入れ子を数えて確認してから反映することにしている。
    教えてもらわなければ、崩れたままだったかもしれない。

    スタンプラリーに挑戦する 行った場所・気になる場所は、現地チェックインでスタンプに残せます。 みんなのコースを見てみる 会員が作ったスポット巡りのコースを都道府県から探せます。自分だけのコースも作れます。 運営者の個人noteも書いています AI活用やサイト運営で気づいたことを、もう少し個人の視点で掘り下げています。

    ※運営者が個人で書いているnoteです。

    技術ブログ一覧へ戻る