mod_sedでウェブを高速化(多分完結)
4月の末からいろいろやってるこの件。まぁ要するにですね、以下の文字列を
1 background-image:url(http://images.example.com/images/jp/bg-global.gif); 2 background-image:url(/images/jp/bg-global.gif); 3 background-image:url(images/jp/bg-global.gif); 4 background-image:url(hmages/jp/bg-global.gif); 5 background-image:url(tmages/jp/bg-global.gif); 6 background-image:url("/images/jp/bg-global.gif"); 7 background-image:url('/images/jp/bg-global.gif');
こう変えたい。
1 background-image:url(http://images.example.com/images/jp/bg-global.gif); 2 background-image:url(http://images.example.com/images/jp/bg-global.gif); 3 background-image:url(http://images.example.com/images/jp/bg-global.gif); 4 background-image:url(http://images.example.com/hmages/jp/bg-global.gif); 5 background-image:url(http://images.example.com/tmages/jp/bg-global.gif); 6 background-image:url("http://images.example.com/images/jp/bg-global.gif"); 7 background-image:url('http://images.example.com/images/jp/bg-global.gif');
面倒なことにいろんなパターンでURLが書かれているので、以下を実現する必要があります。
- httpが入ってるものは変換せずそのまま出す。(1行目)
- "で囲まれている場合は変換後も"で囲む。シングルクオートでも同じ。(6行目、7行目)
- /で始まっていても、/で始まっていなくても/を重ねることなく変換する。(2行目、3行目)
でもってこのところこれらを一行の正規表現で実現しようとしていたんですが、sedでは先読みの否定(?!pattern)が使えないみたい*1ので上記条件の1が実現できませんでした。
でsedならどう実現するかってところに立ち返って考えてみると、sedの分岐を使えばいいということを思いつきました。
bコマンドですね。パターンにマッチした場合にラベルに分岐する機能。C言語的に書けばこんなです。
if (httpが含まれている) なにもしない else s/ほげほげ/ふがふが/g
sedではこう書きます。
/http/ b nop s/ほげほげ/ふがふが/g :nop :end
従って、最終型はこう。
SetOutputFilter DEFLATE OutputSed "/http/ b nop" OutputSed "s/\(url(['\"]*\)\/*\(.*\.[gj][pin]e*[fg]\)/\1http:\/\/images.example.com\/\2/g" OutputSed ":nop" OutputSed ":end" AddoutputFilterByType Sed ; DEFLATE text/css
いやー若いころsed勉強しててよかった。
参考書はこちら。
sed & awkプログラミング 改訂版 (A nutshell handbook)
- 作者: Dale Dougherty,Arnold Robbins,福崎俊博
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 1997/10/01
- メディア: 大型本
- 購入: 2人 クリック: 48回
- この商品を含むブログ (34件) を見る
- 作者: 片山裕
- 出版社/メーカー: インプレス
- 発売日: 1993/03
- メディア: 単行本
- クリック: 2回
- この商品を含むブログ (2件) を見る
*1:mod_rewriteやLocationMatchでは使える