douyi6818 2019-04-03 06:53
浏览 40
已采纳

使用regexp解析Apache日志文件[重复]

This question already has an answer here:

I am parsing an Apache log that I have customised to give me two values only: "time" and "memory" (the values are number of milliseconds and number of bytes) that are both are int64 or float64, but I am using regexp and Go to parse through the file, so when I am matching the contents of the files it return "[]" (empty braces) and is not populating the slice, my code is:

for _, line := range lines {
    var buffer bytes.Buffer

    buffer.WriteString(`\[0-9]+\s`)
    buffer.WriteString(`[0-9]+\s`)
    re1, err := regexp.Compile(buffer.String())

    if err != nil {
        log.Fatalf("regexp: %s", err)
    }
    result := re1.FindStringSubmatch(line)
    fmt.Println(result)
}

When I am printing result, it gives me empty braces and when I am running the whole program, it gives index out of range (which is understandable because result is empty).

My data looks like this:

1040 3952
2849 6832
</div>
  • 写回答

1条回答 默认 最新

  • douwengzao5790 2019-04-03 07:49
    关注

    Regexp is entirely the wrong tool for this job. It will be much easier to read, and much faster to operate, to just use strings.Split or strings.Fields:

    for _, line := range lines {
        fields := strings.Fields(line)
        ms := fields[0]
        size := fields[1]
        fmt.Printf("time: %v, size: %v
    ", ms, size)
    }
    

    If you want to convert these to numbers, you can easily do so with the strconv package, with the additional benefit that it will detect if you get unexpected (non-numeric) input):

    for _, line := range lines {
        fields := strings.Fields(line)
        ms, err := strconv.Itoa(fields[0])
        if err != nil {
            log.Fatalf("time field: %s", err)
        }
        size, err := strconv.Atoi(fields[1])
        if err != nil {
            log.Fatalf("size field: %s", err)
        }
        fmt.Printf("time: %v, size: %v
    ", ms, size)
    }
    


    If you do insist on using a regular expression, at least compile it only once, outside of your for loop:
    re, err := regexp.Compile( ... )
    if err != nil {
        log.Fatalf("regexp: %s", err)
    }
    for _, line := range lines {
        result := re.FindStringSubmatch(line)
        fmt.Println(result)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应