192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=source&module=bibei&app=0&f=9_3_0_0_0`http://192.168.93.55:9090/apk/index.php?app=0`Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.0 Safari/535.7有这么一个字符串,注意里面有这么一个串f=9_3_0_0_0,它可能有,也可能没有,它的位置不固定,只知道肯定在问好后面,`前面,现在要做这么一个事情,试图匹配到f=后面的5个数字(不是固定的), 如果没有f参数,获取全部为空就可以了,请大神出招。谢谢!

解决方案 »

  1.   

    这样?
    preg_match_all('/\bf=([\d_]+)\b/m', $s, $r);
    print_r($r[1]);Array
    (
        [0] => 9_3_0_0_0
    )
      

  2.   

    老大,是这样的,你这个应该是可以的,但是我还需要捕获其他的串,也就是说其他的一定可以捕获,但是这个不确定,它可能存在,可能不存在。所以才有上面一问。我用perl是这么写的,希望你看得懂。[stat@wuhan32 20120331]$ cat 20120331_192.168.93.55_access.plog.filter | grep "2012-03-31 10:02:05" | perl -ne 'if(@o = $_ =~ m#(\d+\.\d+\.\d+\.\d+\`(\d+\-\d+\-\d+ \d+:\d+:\d+)\`GET /([0-9a-zA-Z]{32})/(\d{0,5})/(\d)/apk/index.php\?system=(\w{1,20})&module=(\w{1,20})[^\`]*\bf=(\d+)_(\d+)_(\d+)_(\d+)_(\d+)\b)#){print $_;print join(" | ", @o)."\n\n\n";}else{ print "====" . $_ . "\n\n\n";}'
    ====192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=albums&module=list&app=0`http://192.168.93.55:9090/apk/index.php?system=source&module=bibei&app=0&f=9_3_0_0_0`Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.0 Safari/535.7192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=source&module=bibei&app=0&f=9_3_0_0_0`http://192.168.93.55:9090/apk/index.php?app=0`Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.0 Safari/535.7
    192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=source&module=bibei&app=0&f=9_3_0_0_0 | 2012-03-31 10:02:05 | 91063b13bf8ba59b896804d829b0ff20 | 0 | 0 | source | bibei | 9 | 3 | 0 | 0 | 0
      

  3.   

    #2看不清楚,那个串没有f参数了?这么规律的串,用explode + parse_str会轻松点且代码会清晰点。
      

  4.   

    parse_str确实轻松点,但是由于业务原因,需要用正则来做。我的意思是说需要从串里面获取好几段,有几段是固定有的,但是f在串中可有可无,如果有需要获取,没有就留空
      

  5.   

    嗯,f可有可无,那前面那个app是固定会有的吗,如果是就简单很多。
      

  6.   

    app不一定会有,/91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=source&module=bibei 这一段是固定的
      

  7.   

    试试
    $str = <<<log
    192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=albums&module=list&app=0`http://192.168.93.55:9090/apk/index.php?system=source&module=bibei&app=0&f=9_3_0_0_0`Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.0 Safari/535.7
    192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=source&module=bibei&app=0&f=9_3_0_0_0`http://192.168.93.55:9090/apk/index.php?app=0`Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.0 Safari/535.7
    log;
    preg_match_all('#GET\s*[^`]+\?(?:(?!&f=)[^`])+(?:&f=([0-9_]+)\s*)?(?=`)#i',$str,$m);                                                        
    print_r($m);exit;
    你#9的那个固定串最好结合进来,这样效率也高。
      

  8.   

    192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=albums&module=list&app=0`http://192.168.93.55:9090/apk/index.php?system=source&module=bibei&app=0&ccc=66`Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.0 Safari/535.7随便举一个
      

  9.   

    结果如下,如果没f,会有个空的匹配组。
    Array
    (
        [0] => Array
            (
                [0] => GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=albums&module=list&app=0
                [1] => GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=source&module=bibei&app=0&f=9_3_0_0_0
                [2] => GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=source&module=bibei&t=2&f=9_3_0_0_0
                [3] => GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=albums&module=list&app=0&ccc=666
            )    [1] => Array
            (
                [0] => 
                [1] => 9_3_0_0_0
                [2] => 9_3_0_0_0
                [3] => 
            ))
      

  10.   

    楼主这题目看了半天
    $str=<<<log
    index.php?system=a&f=9_3_0_0_0
    index.php?system=b&f=9_3
    index.php?system=c
    log;
    preg_match_all('/system=(\w+)(?:&f=([\d_]+))?/i',$str,$m);
    print_r($m);
    楼主的意思是 像上面的串,要匹配出system 和 f两个参数,f不存在就留空  对不? 结果如下Array
    (
        [0] => Array
            (
                [0] => system=a&f=9_3_0_0_0
                [1] => system=b&f=9_3
                [2] => system=c
            )
        [1] => Array
            (
                [0] => a
                [1] => b
                [2] => c
            )
        [2] => Array
            (
                [0] => 9_3_0_0_0
                [1] => 9_3
                [2] => 
            )
    )
      

  11.   

    把帖子更新一下:
    192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=albums&module=list&app=0`http://192.168.93.55:9090/apk/index.php?syste
    m=source&module=bibei&app=0&f=9_3_0_0_0`Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.0 Safari/535.7
    192.168.93.24`2012-03-31 10:02:05`GET /91063b13bf8ba59b896804d829b0ff20/0/0/apk/index.php?system=source&module=bibei&app=0&f=9_3_0_0_0`http://192.168.93.55:9090/apk/in
    dex.php?app=0`Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.0 Safari/535.7
    保存一个文件叫 twoline.log
    上面是两行数据下面是php代码<?php$file = file("twoline.log");foreach ($file as $line)
    {
            preg_match("(\d+\.\d+\.\d+\.\d+\`(\d+\-\d+\-\d+ \d+:\d+:\d+)\`GET /([0-9a-zA-Z]{32})/(\d{0,5})/(\d)/apk/index.php\?system=(\w{1,20})&module=(\w{1,20})[^`]*(?:&
    f=(9_3_0_0_0))?)", $line, $m);        var_dump($m);
    }
      

  12.   

    preg_match("(\d+\.\d+\.\d+\.\d+\`(\d+\-\d+\-\d+ \d+:\d+:\d+)\`GET /([0-9a-zA-Z]{32})/(\d{0,5})/(\d)/apk/index.php\?system=(\w{1,20})&module=(\w{1,20})[^`]*(?:&
    f=(9_3_0_0_0))?)", $line, $m);
    ------------------------------------------------
    嗯,问题在于那个[^`]*,这个已经把f=9_3_0..匹配了。
    所以为什么我在#12楼要这么写
    (?:(?!&f=)[^`])+
    就是[^`]+先匹配不带有&f=的串
    或许你的情况应该用*而不是+
    (?:(?!&f=)[^`])*
      

  13.   

    总结一下 
    第一种方法:
    preg_match("#\d+\.\d+\.\d+\.\d+\`(\d+\-\d+\-\d+ \d+:\d+:\d+)\`GET /([0-9a-zA-Z]{32})/(\d{0,5})/(\d)/apk/index.php\?system=(\w{1,20})&module=(\w{1,20})(?:(?!&f=
    )[^`])*(?:&f=(?:(\d+)_(\d+)_(\d+)_(\d+)_(\d+)))?[^`]*#", $line, $m);第二种方法:
    preg_match("#\d+\.\d+\.\d+\.\d+\`(\d+\-\d+\-\d+ \d+:\d+:\d+)\`GET /([0-9a-zA-Z]{32})/(\d{0,5})/(\d)/apk/index.php\?system=(\w{1,20})&module=(\w{1,20})(?:[^`]*&
    f=(?:(\d+)_(\d+)_(\d+)_(\d+)_(\d+)))?[^`]*#", $line, $m);两种方法均可行,感谢foolbirdflyfirst说明原因