亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

golang中的正則表達式命名組

golang中的正則表達式命名組

Go
揚帆大魚 2022-05-17 16:48:38
我需要幫助將正則表達式與 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 mainimport (    "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
查看完整描述

2 回答

?
慕運維8079593

TA貢獻1876條經驗 獲得超5個贊

單匹配解決方案


由于您定義了捕獲組并需要提取它們的值,因此您需要使用.FindStringSubmatch,請參閱此 Go lang 演示:


package main


import (

    "fmt"

    "regexp"

)


func main() {

    var re = regexp.MustCompile(`(?P<ip>\S+).+?\[(?P<localtime>.*?)\].+?GET\s/\?(?P<request>.+?)".+?"(?P<ref>.+?)"\s*"(?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"`

    result := make(map[string]string) 

    match := re.FindStringSubmatch(str) 

    for i, name := range re.SubexpNames() {

        if i != 0 && name != "" {

            result[name] = match[i]

        }

    }

    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.86

Local Time: 06/Feb/2020:00:11:04 +0100

Request: parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1

Ref: 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 main


import (

    "fmt"

    "regexp"

)


func main() {

    var re = regexp.MustCompile(`(?P<ip>\S+).+?\[(?P<localtime>.*?)\].+?GET\s/\?(?P<request>.+?)".+?"(?P<ref>.+?)"\s*"(?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"`

    result := make([]map[string]string,0) 

    for _, match := range re.FindAllStringSubmatch(str, -1) {

        res := make(map[string]string)

        for i, name := range re.SubexpNames() {

            if i != 0 && name != "" {

                res[name] = match[i]

            }

        }

        result = append(result, res)

    }


    // Displaying the matches

    for i, match := range(result) {

        fmt.Printf("--------------\nMatch %d:\n", i+1)

        for i, name := range re.SubexpNames() {

            if i != 0 && name != "" {

                fmt.Printf("Group %s: %s\n", name, match[name]) 

            }

        }

    }

}

輸出:


--------------

Match 1:

Group ip: 57.157.87.86

Group localtime: 06/Feb/2020:00:11:04 +0100

Group request: parammore=1&customer_id=1&version=1.56&param=meaningful&customer_name=somewebsite.de&some_id=4&cachebuster=1580944263903 HTTP/1.1

Group 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


查看完整回答
反對 回復 2022-05-17
?
當年話下

TA貢獻1890條經驗 獲得超9個贊

您可以為此使用regroup https://github.com/oriser/regroup。


例子:


package main


import (

    "fmt"


    "github.com/oriser/regroup"

)


type LogEntry struct {

    IP        string `regroup:"ip"`

    LocalTime string `regroup:"localtime"`

    Request   string `regroup:"request"`

    Ref       string `regroup:"ref"`

    Agent     string `regroup:"agent"`

}


func main() {

    var re = regroup.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"`


    logEntry := &LogEntry{}

    if err := re.MatchToTarget(str, logEntry); err != nil {

        panic(err)

    }


    fmt.Printf("%#v\n", logEntry)

}


查看完整回答
反對 回復 2022-05-17
  • 2 回答
  • 0 關注
  • 158 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號