[PHP-users 28865] Re: Apacheのaccess.logから検索ワードを抽出して集計したい

安井 evelinae @ mac.com
2006年 3月 29日 (水) 03:58:06 JST


安井と申します。

At Tue, 28 Mar 2006 18:34:23 +0900,
k.kikuchi wrote:
> 
> 正規表現の知識ゼロにperlの知識も全くないため、
> phpにて見よう見まねでコーディング中です。
ついでだから、正規表現の勉強も :-)

> Apacheのaccess.log自体のフォーマットは以下の通りです。
>
> ■ログフォーマット
> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
> 
> 
> ■コード
> -----------------------------------------------------------
> <?php
> 
> $fp_in = fopen('access_log', 'r');
> $fp_out = fopen('out.log', 'w');
> $pattern =
>  'http:\/\/www\.google\.co(.*)\/search\?(.*)$'.
>  '(/[-.!~*\d\w;/?:@&=+$,%#]+)?';
... 略 ...
> if (ereg ( $pattern, $data, $url )) {
... 略 ...
> ?>
> -----------------------------------------------------------

URL の / をエスケープしているみたいですが、eregを使っているようなので、エスケープする必要は無いと思います。
そして、URLの?以降の文字列を取ろうとしていますが、文字列の最後を意味する $ があるため、期待通りに取れないのだと思います。

そしてログフォーマットを見ると、"%{Referer}i"と Refererの最後には " が付いてます。
つまり、"http://www.google.co(.*)/search?..." の...を取りたいので、"が出てこない限りマッチするようにします。

ですので正規表現は、'http://www.google.co([a-z\.]*)/search\?([^"]+)' といった形になると思います。

以上です。

# かなり余談ですが、コマンドラインの場合です。
# awk&sed だと、
# awk '($11~/http:\/\/www.google.co[a-z\.]*\//){print $11;}' access_log | \
#  sed -e 's/http:\/\/www.google.co[a-z\.]*\/search?//g' -e 's/"//g' 
# となって、Perlだと、
# perl -e 'while(<>){if(m,http://www.google.co[a-z\.]+/search\?([^"]+),){print "${1}\n";}}' access_log
# になるかと...



PHP-users メーリングリストの案内