- 论坛徽章:
- 0
|
- 1273144492.670 9 121.14.225.183 TCP_IMS_HIT/304 236 GET http://www.ggv.com.cn/downfiles/20070815_135941_1.rar - NONE/- text/plain "http://down.ggv.com.cn/down/cnt_n_down.php?id=698400&flag=1" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
- 脚本里相关部分是:
- my $log_pattern = qr '^.*?\d+\s+\w+\s+(http:\/\/.+?)\s+.+';
复制代码 没有什么想不明白的。正则表达式只是为了写得尽可能准确。越准确正则引擎需要做的猜测类工作越少,性能相对越好。
正则分解如下:
/
^.*? # 前面那些
\d+ # 上面的236
\s+ # 空白
\w+ # GET
\s+ # 空白
(http:\/\/.+?) # url
\s+ # 空白
.+ # 后面剩余的
/
这个正则不一定非要这样写,但目的只有两个:
1. 能够匹配,这是做这件事的根本目的,
2. 严谨,如果使用split速度肯定更快,但是如果日志里有不完整或者残缺或者不准确的日志的话,split将出问题,而且直接使用split (//, @list)[7]可能会被perl报一个uninitialized value的错误信息;
3. 正则写的相对完整,完整意味着“描述上没有含糊不清,更精确”,体现了2的严谨,也能提高速度。否则直接写个:
^.*?http:\/\/.+\s+.+就能匹配出来了,但速度上你可以测试下。
但是这个正则前面的.*?可以进行进一步优化。因为这样正则引擎在匹配的时候可能需要做的步骤是:
因为加了非贪婪的?,首先匹配:
将.*?当成空白跟后面的正则加在一起,看能否匹配成功,如果匹配失败,则:
将.*?当成一个字符,进行匹配,如果匹配失败,则:
再向右读取一个字符再匹配,循环,一直到匹配成功为止。 |
|