正規表現で16本の記事を壊した。「どこまで取るか」を図にした

既定の指定は取れるだけ取ります。この性質で、実際にこのサイトの記事16本の本文を壊しました。何が起きたのかを図で説明します。

この記事の結論

  1. 既定の指定は取れるだけ取る。これが事故のもとになる
  2. 最小で止める指定を付けても、改行に合う指定を一緒に付けると区切りを越える
  3. 実際にこのサイトで16本の記事の本文を壊した
  • 既定の指定は取れるだけ取る。これが事故のもとになる
  • 最小で止める指定を付けても、改行に合う指定を一緒に付けると区切りを越える
  • 実際にこのサイトで16本の記事の本文を壊した

このサイトの出典の書き方を直す置換を書いて、記事16本の本文を丸ごとリンクにしたことがある。原因は正規表現の「どこまで取るか」だった。

同じ対象に対して既定の指定では範囲を広く取り、最小で止める指定では1件ずつ取れることを色分けで比べた図
図1:同じ対象でも、どこまで取るかで結果がまるごと変わる。

既定は「取れるだけ取る」

仕様の説明はこうなっている。

既定では * や + のような量指定子は貪欲(greedy)であり、できるだけ多くの回数に合わせようとする。

そして、最小で止めるほうはこう書かれている。

量指定子のあとに ? を付けると非貪欲になる。つまり、最小の回数が見つかった時点で止まる。

公式の例が分かりやすい

対象が some <foo> <bar> new </bar> </foo> thing のとき、結果はこうなる。

書き方合う範囲
<.*><foo> <bar> new </bar> </foo>(最後まで一息に取る)
<.*?><foo>(最初で止まる)

書いたのは同じ1文字の違いで、取れる範囲がこれだけ変わる。

SPONSORED

実際に壊したときの話

出典の一覧で、リンクの文字をURLそのものから名称に変えたかった。書いたのは、おおよそこういう形だった。

<li>(.*?)<a href=… に、改行にも合う指定を付けたもの

最小で止める指定は付けている。それでも足りなかった。

なぜ越えたか

最小で止めるのは「次に続きが見つかるところまで」であって、「区切りの手前まで」ではない。

1つ目の項目の中に続きが無ければ、区切りを越えて次の項目まで探しに行く。改行に合う指定を付けたことで、行をまたぐことも妨げられなかった。

結果、項目と項目の間にあった本文がまるごとリンクの中に入った。記事を開くと、本文全体が青い下線になっていた。16本すべてで同じことが起きた。

直し方と、入れた検査

直した形は単純で、一息に書くのをやめた。

  1. まず <li>…</li> を1件ずつ取り出す
  2. 取り出したその中だけを置換する
  3. 置換後にリンクの中にブロック要素が入っていないかを調べる
  4. 入っていたら書き戻さずに中止する

3番目と4番目が要点になる。壊れたことを、公開する前に機械で気づける形にする。見た目で確認する運用にすると、16本あれば必ず見落とす。

決めたこと

この一件から、置換を書くときの決まりを2つ置いた。

  • 本文をまたげる書き方をしない。区切りで先に切ってから中を処理する
  • 書いてしまったら、必ず検査を付ける。検査が無い置換は流さない

以後の置換は、先読みで区切る形だけを使っている。サーバー側の検査と同じ考え方で、信用せずに確かめる側を用意する。

覚えておく書き方

書き方意味気をつけること
.任意の1文字既定では改行に合わない
* +0回以上/1回以上既定で取れるだけ取る
?0回か1回量指定子の後ろに付けると最小で止まる
[ ]この中のどれか1文字[^ ] は「この中以外」
( )まとめて覚える後から取り出せる
^ $先頭/末尾行ごとにする指定で挙動が変わる

1行目が効いてくる。改行に合わないのが既定だからこそ、改行に合う指定を足した瞬間に範囲が広がる。

行単位で絞る話はgrepは行ごとに見ているだけに書いた。あちらは行をまたがないことが守りになっている例になる。

まとめ

  • 既定の量指定子はできるだけ多くの回数に合わせようとする
  • 後ろに ? を付けると最小の回数で止まる
  • 最小で止めても、区切りの手前で止まるわけではない
  • 改行に合う指定を足すと行をまたぐ。これで16本を壊した
  • 直し方は区切りで先に切り出してから、中だけ処理する
  • 置換には壊れを機械で見つける検査を必ず付ける
SPONSORED

出典

図は本記事のために作成したもの。壊した件は、このサイトで2026年10月に実際に起きたもの。

新しい記事が出たら、ブラウザの通知でお知らせします。

メールアドレスの登録は要りません。いつでも止められます。

AUTHOR

北海道のWEB屋

北海道を拠点に、Web業界14年・サポート実績1,000件以上。WordPressの復旧、サーバー移転、独自ドメインとメールの設定、PHP・JavaScriptの修正まで対応します。相談と見積もりは無料です。

SPONSORED

関連記事

RELATED