golang中的正则表达式命名组

我需要帮助将正则表达式与 golang 集成。我想解析日志文件并创建一个在https://regex101.com/r/p4mbiS/1/上看起来很好的正则表达式


日志线如下所示:


57.157.87.86 - - [06/Feb/2020:00:11:04 +0100] "GET /?parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1" 204 0 "https://www.somewebsite.com/more/andheresomemore/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"

像这样的正则表达式:


(?P<ip>([^\s]+)).+?\[(?P<localtime>(.*?))\].+?GET\s\/\?(?P<request>.+?)\".+?\"(?P<ref>.+?)\".\"(?P<agent>.+?)\"

命名组的结果应如下所示:


ip: 57.157.87.86


当地时间:06/Feb/2020:00:11:04 +0100


请求:parammore=1&customer_id=1&...HTTP/1.1


参考:https ://www.somewebsite.com/more/andheresomemore/


代理:Mozilla/5.0(Windows NT 10.0;Win64;x64;rv:72.0)...


regex101.com 生成对我不起作用的 golang 代码。我试图改进它但没有成功。


golang 代码只返回整个字符串而不是组。


package main


import (

    "regexp"

    "fmt"

)


func main() {

    var re = regexp.MustCompile(`(?P<ip>([^\s]+)).+?\[(?P<localtime>(.*?))\].+?GET\s\/\?(?P<request>.+?)\".+?\"(?P<ref>.+?)\".\"(?P<agent>.+?)\"`)

    var str = `57.157.87.86 - - [06/Feb/2020:00:11:04 +0100] "GET /?parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1" 204 0 "https://www.somewebsite.com/more/andheresomemore/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"`

    

    if len(re.FindStringIndex(str)) > 0 {

        fmt.Println(re.FindString(str),"found at index",re.FindStringIndex(str)[0])

    }

}

在这里找到小提琴https://play.golang.org/p/e0_8PM-Nv6i


扬帆大鱼
浏览 215回答 2
2回答

慕运维8079593

单匹配解决方案由于您定义了捕获组并需要提取它们的值,因此您需要使用.FindStringSubmatch,请参阅此 Go lang 演示:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "regexp")func main() {&nbsp; &nbsp; var re = regexp.MustCompile(`(?P<ip>\S+).+?\[(?P<localtime>.*?)\].+?GET\s/\?(?P<request>.+?)".+?"(?P<ref>.+?)"\s*"(?P<agent>.+?)"`)&nbsp; &nbsp; var str = `57.157.87.86 - - [06/Feb/2020:00:11:04 +0100] "GET /?parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1" 204 0 "https://www.somewebsite.com/more/andheresomemore/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"`&nbsp; &nbsp; result := make(map[string]string)&nbsp;&nbsp; &nbsp; match := re.FindStringSubmatch(str)&nbsp;&nbsp; &nbsp; for i, name := range re.SubexpNames() {&nbsp; &nbsp; &nbsp; &nbsp; if i != 0 && name != "" {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result[name] = match[i]&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("IP: %s\nLocal Time: %s\nRequest: %s\nRef: %s\nAgent: %s\n",result["ip"], result["localtime"], result["request"], result["ref"], result["agent"])}输出:IP: 57.157.87.86Local Time: 06/Feb/2020:00:11:04 +0100Request: parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1Ref: https://www.somewebsite.com/more/andheresomemore/Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0在模式中如此频繁地使用它不是一个好主意,.+?因为它会降低性能,因此我用否定字符类替换了那些点模式,并试图使模式更加冗长。多匹配解决方案在这里,您需要使用regexp.FindAllStringSubmatch:请参阅此 Go 演示:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "regexp")func main() {&nbsp; &nbsp; var re = regexp.MustCompile(`(?P<ip>\S+).+?\[(?P<localtime>.*?)\].+?GET\s/\?(?P<request>.+?)".+?"(?P<ref>.+?)"\s*"(?P<agent>.+?)"`)&nbsp; &nbsp; var str = `57.157.87.86 - - [06/Feb/2020:00:11:04 +0100] "GET /?parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1" 204 0 "https://www.somewebsite.com/more/andheresomemore/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"`&nbsp; &nbsp; result := make([]map[string]string,0)&nbsp;&nbsp; &nbsp; for _, match := range re.FindAllStringSubmatch(str, -1) {&nbsp; &nbsp; &nbsp; &nbsp; res := make(map[string]string)&nbsp; &nbsp; &nbsp; &nbsp; for i, name := range re.SubexpNames() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if i != 0 && name != "" {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res[name] = match[i]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; result = append(result, res)&nbsp; &nbsp; }&nbsp; &nbsp; // Displaying the matches&nbsp; &nbsp; for i, match := range(result) {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("--------------\nMatch %d:\n", i+1)&nbsp; &nbsp; &nbsp; &nbsp; for i, name := range re.SubexpNames() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if i != 0 && name != "" {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Group %s: %s\n", name, match[name])&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}输出:--------------Match 1:Group ip: 57.157.87.86Group localtime: 06/Feb/2020:00:11:04 +0100Group request: parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1Group ref: https://www.somewebsite.com/more/andheresomemore/Group agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0

当年话下

您可以为此使用regroup https://github.com/oriser/regroup。例子:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "github.com/oriser/regroup")type LogEntry struct {&nbsp; &nbsp; IP&nbsp; &nbsp; &nbsp; &nbsp; string `regroup:"ip"`&nbsp; &nbsp; LocalTime string `regroup:"localtime"`&nbsp; &nbsp; Request&nbsp; &nbsp;string `regroup:"request"`&nbsp; &nbsp; Ref&nbsp; &nbsp; &nbsp; &nbsp;string `regroup:"ref"`&nbsp; &nbsp; Agent&nbsp; &nbsp; &nbsp;string `regroup:"agent"`}func main() {&nbsp; &nbsp; var re = regroup.MustCompile(`(?P<ip>([^\s]+)).+?\[(?P<localtime>(.*?))\].+?GET\s\/\?(?P<request>.+?)\".+?\"(?P<ref>.+?)\".\"(?P<agent>.+?)\"`)&nbsp; &nbsp; var str = `57.157.87.86 - - [06/Feb/2020:00:11:04 +0100] "GET /?parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1" 204 0 "https://www.somewebsite.com/more/andheresomemore/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"`&nbsp; &nbsp; logEntry := &LogEntry{}&nbsp; &nbsp; if err := re.MatchToTarget(str, logEntry); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("%#v\n", logEntry)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go