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

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

匹配直到字符,但是,不要包含該字符

匹配直到字符,但是,不要包含該字符

Go
千萬里不及你 2022-09-19 10:43:43
我正在嘗試與以下輸入進行匹配:foo=bar baz foo:1  foo:234.mds32  notfoo:baz  foo:bak foo:nospace foo:bar和輸出 6 匹配:除 .匹配項應類似(即不包括尾隨空格或前導空格。notfoofoo:bar一般來說,我試圖匹配的規則是:查找任何 kv 對,其中鍵為 ,并且 kv 對由 或 分隔。foo=:對是彼此分離的字符串。kv 對之間可能有多個空格或隨機字符串。作為 ^ 的結果,kv 對必須在兩側具有空格或行開始/結束。我目前對此最好的正則表達式是 ,然后提取組。'(?:\s|^)(?P<primary>foo[:=].+?)\s'primary這樣做的問題是因為我們包含作為匹配的一部分,我們遇到了重疊正則表達式的問題:因為我們嘗試空格字符匹配2x,并且golang正則表達式不返回重疊匹配項。\sfoo:bak foo:nospace foo:bar在其他正則表達式引擎中,我認為可以使用前瞻,但據我所知,golang正則表達式不允許這樣做。有什么辦法可以做到這一點嗎?去游樂場鏈接: https://play.golang.org/p/n8gnWwpiBSR
查看完整描述

3 回答

?
慕仙森

TA貢獻1827條經驗 獲得超8個贊

遺憾的是,Go中沒有外觀支持,因此,您可以通過加倍空格(例如與\s)然后與匹配來解決此問題:regexpregexp.MustCompile().ReplaceAllString(d, "$0$0")(?:\s|^)(?P<primary>foo[:=]\S+(?:\s+[^:\s]+)*)(?:\s|$)


package main


import (

    "fmt"

    "regexp"

)


func main() {

    var d = `foo=bar baz foo:1  foo:234.mds32  notfoo:baz  foo:bak foo:nospace foo:bar`

    d = regexp.MustCompile(`\s`).ReplaceAllString(d, "$0$0")

    r := regexp.MustCompile(`(?:\s|^)(?P<primary>foo[:=]\S+(?:\s+[^:\s]+)*)(?:\s|$)`)

    idx := r.SubexpIndex("primary")

    for _, m := range r.FindAllStringSubmatch(d, -1) {

        fmt.Printf("%q\n", m[idx])

    }

}

請參閱 Go 演示。輸出:


"foo=bar  baz"

"foo:1"

"foo:234.mds32"

"foo:bak"

"foo:nospace"

"foo:bar"

詳細信息

  • (?:\s|^)- 空格或字符串的開頭

  • (?P<primary>foo[:=]\S+(?:\s+[^:\s]+)*)- 組“主要”:冒號或字符,一個或多個非空格,然后零個或多個出現一個或多個空格,然后是一個或多個字符,而不是空格或冒號foo=

  • (?:\s|$)- 白帶或字符串的末端。


查看完整回答
反對 回復 2022-09-19
?
aluckdog

TA貢獻1847條經驗 獲得超7個贊

您可以采取以下幾種方法:

  1. 只需將您的模式更改為維克托·斯特里比紐在評論中提到的模式,而不是匹配。這解決了沒有惡作劇的問題,但我會列出一些可能適用于類似問題的選擇,這些問題不能輕易被否定。(?:\s|^)(?P<primary>foo[:=]\S+).+?\s

  2. 由于問題在于功能不允許重疊,因此不要使用它們!相反,滾動你自己的,用于獲取一個匹配項的邊界,通過切片字符串來提取匹配的文本,然后執行并循環直到返回零。FindAllFindStringSubmatchIndexd = d[endIndex-1:]FindStringSubmatchIndex

  3. 使用 模式將輸入字符串分解為空格分隔的組件,然后丟棄不在 上的組件。您甚至可以改用。其余的將是您想要的匹配項,并且它們周圍的空格將被拆分丟棄。在我看來,這個版本比試圖使用匹配更清楚地傳達了意圖。regexp.Split()\s+regexp.Match()^foo[:=]strings.HasPrefix("foo:") || strings.HasPrefix("foo=")


查看完整回答
反對 回復 2022-09-19
?
哈士奇WWW

TA貢獻1799條經驗 獲得超6個贊

其他人根據要求使用正則表達式給出了很好的答案。我可以大膽地建議一個非正則表達式的答案嗎?


我發現正則表達式不是這種情況的最佳解決方案。最好使用拆分字符串以獲取子字符串列表。對于每個字符串,根據它是否具有或兩者都沒有來拆分它。該函數在解析方面做得很好,類似于 中的默認拆分,它跳過了一行中的多個空格。strings.Fields(original)=:Fields()awk


工作示例:https://play.golang.org/p/xXaA9skdplz



    original := `foo=bar baz foo:1  foo:234.mds32  notfoo:baz  foo:bak foo:nospace foo:bar`


    for _, item := range strings.Fields(original) {

        if kv := strings.SplitN(item, "=", 2); len(kv) == 2 {

            fmt.Printf("key/value: %q -> %q\n", kv[0], kv[1])

        } else if kv := strings.SplitN(item, ":", 2); len(kv) == 2 {

            fmt.Printf("key/value: %q -> %q\n", kv[0], kv[1])

        } else {

            fmt.Printf("key: %q\n", item)

        }


    }

顯然,您需要修改此代碼以收集答案而不是打印它們。


如果您必須使用正則表達式,請使用其他答案。


查看完整回答
反對 回復 2022-09-19
  • 3 回答
  • 0 關注
  • 118 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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