日志分析 正则表达式一例 详解

SysTem128 2008-01-17 11:14:52
原题:
http://topic.csdn.net/u/20080117/17/ee25a739-515e-493d-bc20-40887d1fb4dc.html
<?php
$data = "
Dec 25 10:02:10 192.168.0.213 syslog-ng[22683]: syslog-ng starting up; version='2.0.6'
Dec 25 10:02:23 192.168.0.213 CRON[22595]: pam_unix(cron:session): session closed for user www-data
Dec 25 10:02:51 192.168.0.213 shutdown[22761]: shutting down for system reboot
Dec 25 10:02:54 192.168.0.213 init: Switching to runlevel: 6
Dec 25 10:03:02 192.168.0.213 kernel: CPU0: Temperature/speed normal
Dec 25 10:03:10 192.168.0.213 watchdog[2962]: stopping daemon (5.4)
Dec 25 10:03:10 192.168.0.213 wd_keepalive[22852]: starting watchdog keepalive daemon (5.4): int=10 alive=(null) realtime=yes
Dec 25 10:03:10 192.168.0.213 wd_keepalive[22852]: stopping watchdog keepalive daemon (5.4)
Dec 25 10:03:23 192.168.0.213 rpc.statd[2040]: Caught signal 15, un-registering and exiting.
Dec 25 10:03:24 192.168.0.213 ntop[2683]: CLEANUP[t3054491312]: ntop caught signal 15
Dec 25 10:03:24 192.168.0.213 ntop[2683]: THREADMGMT[t3054491312]: ntop RUNSTATE: SHUTDOWN(7)
";
preg_match_all('/([\w]{3}[\s]+[\d]{1,2}[\s]+[\d:]{5,8})[\s]+([0-9\.]{7,15})[\s]+([\w\-\.]+?)(?(?=\[[\d]+\])\[([\d]+)\]):(.+)/i',$data,$a);
print_r($a);
# 讲解
#'/([\w]{3}[\s]+[\d]{1,2}[\s]+[\d:]{5,8})[\s]+([0-9\.]{7,15})[\s]+([\w\-\.]+?)(?(?=\[[\d]+\])\[([\d]+)\]):(.+)/i'
# 时间匹配开始
# [\w]{3} 1,匹配三位任一“字”的字符
# [\s]+ 2,匹配多位空白符
# [\d]{1,2} 3,匹配由一到两位的数字
# [\s]+ 4,匹配多位空白符
# [\d:]{5,8} 5,匹配五到八位由十进制数字和冒号组成的字符串 ;
# 时间匹配结束
# [\s]+ 1,匹配多位空白符
# Ip匹配开始
# [\d\.]{7,15} 1,匹配七到十五位由十进制数字和点号组成的字符串 ;
# Ip匹配结束
# [\s]+ 1,匹配多位空白符
# 程序匹配开始
# ([\w\-\.]+?) 1,匹配任一'字',点号和'-'号.
# 程序匹配结束
# 端口匹配开始
# (?(?=\[[\d]+\])\[([\d]+)\]) 1,条件匹配 如有匹配 [一位或多位十进制数字] 的字符串 则取出数字,即执行后面的 \[([\d]+)\] 匹配.
# 端口匹配结束
# : 1,匹配冒号
# 描述匹配开始
# (.+) 1,匹配除了换行符外的任意一个字符(默认情况下)
# 描述匹配结束
# /i 1,i 模式修正符 “如果设定此修正符,模式中的字符将同时匹配大小写字母” 即 不区分大小写
?>

多有不足请君斧正.
...全文
907 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
银熊 2008-03-05
  • 打赏
  • 举报
回复
正在学习正则呢
xw2423 2008-02-02
  • 打赏
  • 举报
回复
受教,拜读了!
simaopig 2008-01-20
  • 打赏
  • 举报
回复
呵呵。。受教了。。

这几天正好看到正则表达式,连皮毛都不懂。


见笑了。。呵。。以后有东西教我啊。。哈。。
SysTem128 2008-01-19
  • 打赏
  • 举报
回复

/[\d:]{5,8}/


这是一个惯用技巧(或窍门,Hack……).
这个Log的格式是固定的,时间是双位补0的,这时你不必考虑像你提出的 12311:22 这种字符串.
就算有 12311:22 出现.我们有责任将其提取出来,而并不是当作不匹配记录忽略掉.
Ip也是同理,如果要匹配到IPv6改变其最大长度为 23(5*1+3*6) 即可.

端口的提取用的是
Conditional subpatterns
源例是这样的

(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)

范例

(?(?=[^a-z]*[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )


你可以这样理解
如字符串符合 condition 则 这整个子句,即(?(condition)yes-pattern)或(?(condition)yes-pattern|no-pattern)被替换为yes-pattern.
反之如字符串不匹配 condition 则着整个子句被替换为no-pattern.如no-pattern不存在则整个子句被替换为空.


(?(?=\[[\d]+\])\[([\d]+)\])

意思就是:如果字符串 由[开头]结尾且中间包含至少1个十进制数字即/\[[\d]+\]/ 则 进行后面的子匹配即 /\[([\d]+)\]/ .

simaopig 2008-01-19
  • 打赏
  • 举报
回复
/(\d[1,2]:){2}\d[1,2]/
simaopig 2008-01-19
  • 打赏
  • 举报
回复
。。。我发现你写的不规范。

例如:
/[\d:]{5,8}/

你是可以匹配出他这个题目里的时间,

但是匹配的格式其实是不正确的。。

该正则表达式还可以匹配12311:22 这样的字符串。

/\d[1,2]:\d[1,2]:\d[1,2]/ 这样好些。。

但是这个也不规范。。因为没有考虑到时间的取值范围。。。
simaopig 2008-01-19
  • 打赏
  • 举报
回复
(?(?=expression)yes|no)

替换构造。

(?(?=\[[\d]+\])\[([\d]+)\]) 1,条件匹配 如有匹配 [一位或多位十进制数字] 的字符串 则取出数字,即执行后面的 \[([\d]+)\] 匹配.

\[[\d]+\] 以中括号左面“[”开始,里面有一个或多个十进制数字,然后是中括号号右边“]”结束


\[([\d]+)\] 以中括号左面“[”开始 子模式:是一个或多个十进制数字 中括号右边“]”


主要就是为了看有没有匹配上面的模式,如果有的话输出下面的那个正则里的子模式


也不知道我理解的对不对。呵。。

simaopig 2008-01-19
  • 打赏
  • 举报
回复
楼主写的真是精彩。
[\d:]{5,8} 5,匹配五到八位由十进制数字和冒号组成的字符串 ;
因为时间最长八位,最短五位
10:02:10 8个字符 0:0:0 5个字符

[\d\.]{7,15} 1,匹配七到十五位由十进制数字和点号组成的字符串
同理,IP最长十五位,最短七位
192.168.168.168 15位 0.0.0.0 7位


不过和上面的一样。那个端口的匹配是怎么回事?有点没看懂。
望楼主给解答一下。谢谢。
hjc1984117 2008-01-18
  • 打赏
  • 举报
回复
有些地方还是不明白
1:[\d:]{5,8} 匹配五到八位由十进制数字和冒号组成的字符串 (为什么是5到8位呢?)
2:\d\.]{7,15} 1,匹配七到十五位由十进制数字和点号组成的字符串 (为什么是7到10位呢?)
3:(?(?=\[[\d]+\])\[([\d]+)\]) 条件匹配 如有匹配 [一位或多位十进制数字] 的字符串 则取出数字,即执行后面的 \[([\d]+)\] 匹配(看不怎么懂)
hjc1984117 2008-01-18
  • 打赏
  • 举报
回复
太好了,太感谢你了!!!

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧