首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 日志分析 正则表达式一例 详解 [已结贴,结贴人:SysTem128]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • SysTem128
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 揭帖率:
    发表于:2008-01-17 23:14:52 楼主
    原题:
    http://topic.csdn.net/u/20080117/17/ee25a739-515e-493d-bc20-40887d1fb4dc.html
    PHP code
    <?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 模式修正符 “如果设定此修正符,模式中的字符将同时匹配大小写字母” 即 不区分大小写 ?>

    多有不足请君斧正.
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hjc1984117
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-01-18 10:27:411楼 得分:0
    太好了,太感谢你了!!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hjc1984117
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-01-18 10:51:072楼 得分:0
    有些地方还是不明白
    1:[\d:]{5,8}    匹配五到八位由十进制数字和冒号组成的字符串 (为什么是5到8位呢?)
    2:\d\.]{7,15}  1,匹配七到十五位由十进制数字和点号组成的字符串 (为什么是7到10位呢?)
    3:(?(?=\[[\d]+\])\[([\d]+)\]) 条件匹配 如有匹配 [一位或多位十进制数字] 的字符串 则取出数字,即执行后面的 \[([\d]+)\] 匹配(看不怎么懂)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • simaopig
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-01-19 15:00:073楼 得分:0
    楼主写的真是精彩。
    [\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位


    不过和上面的一样。那个端口的匹配是怎么回事?有点没看懂。
    望楼主给解答一下。谢谢。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • simaopig
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-01-19 15:22:224楼 得分:0
    (?(?=expression)yes|no)

    替换构造。

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

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


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


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


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

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • simaopig
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-01-19 17:58:435楼 得分:0
    。。。我发现你写的不规范。

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

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

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

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

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

    但是这个也不规范。。因为没有考虑到时间的取值范围。。。 
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • simaopig
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-01-19 18:01:016楼 得分:0
    /(\d[1,2]:){2}\d[1,2]/
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • SysTem128
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-01-19 21:38:357楼 得分:0
    Assembly code
    /[\d:]{5,8}/


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

    端口的提取用的是
    Conditional subpatterns
    源例是这样的
    Assembly code
    (?(condition)yes-pattern) (?(condition)yes-pattern|no-pattern)

    范例
    PHP code
    (?(?=[^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不存在则整个子句被替换为空.


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

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

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • simaopig
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-01-20 13:35:508楼 得分:10
    呵呵。。受教了。。

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


    见笑了。。呵。。以后有东西教我啊。。哈。。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xw2423
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-02 13:20:489楼 得分:10
    受教,拜读了!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • kissweb
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-03-05 16:38:2610楼 得分:0
    正在学习正则呢
    修改 删除 举报 引用 回复