使用regexp解析Apache日志文件

时间:2019-04-03 06:53:26

标签: regex apache parsing go logging

我正在解析一个自定义的Apache日志,仅给我两个值:“ time”和“ memory”(值是毫秒数和字节数),它们都是int64或float64,但是我是使用regexp和Go来解析文件,所以当我匹配文件的内容时,它返回“ []”(空括号)并且没有填充切片,我的代码是:

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)
}

当我打印结果时,它给了我大括号,而当我运行整个程序时,它给了索引超出范围(这是可以理解的,因为结果为空)。

我的数据如下:

1040 3952
2849 6832

1 个答案:

答案 0 :(得分:0)

正则表达式完全是这项工作的错误工具。仅使用strings.Splitstrings.Fields会更容易阅读,操作起来也更快:

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

如果您想将它们转换为数字,可以使用strconv包轻松实现,并具有额外的好处,它将检测出是否收到了意外的(非数字)输入):

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\n", ms, size)
}


如果您确实坚持使用正则表达式,请在for循环之外至少编译一次:

re, err := regexp.Compile( ... )
if err != nil {
    log.Fatalf("regexp: %s", err)
}
for _, line := range lines {
    result := re.FindStringSubmatch(line)
    fmt.Println(result)
}