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|$)
- 白帶或字符串的末端。

TA貢獻1847條經驗 獲得超7個贊
您可以采取以下幾種方法:
只需將您的模式更改為維克托·斯特里比紐在評論中提到的模式,而不是匹配。這解決了沒有惡作劇的問題,但我會列出一些可能適用于類似問題的選擇,這些問題不能輕易被否定。
(?:\s|^)(?P<primary>foo[:=]\S+)
.+?
\s
由于問題在于功能不允許重疊,因此不要使用它們!相反,滾動你自己的,用于獲取一個匹配項的邊界,通過切片字符串來提取匹配的文本,然后執行并循環直到返回零。
FindAll
FindStringSubmatchIndex
d = d[endIndex-1:]
FindStringSubmatchIndex
使用 模式將輸入字符串分解為空格分隔的組件,然后丟棄不在 上的組件。您甚至可以改用。其余的將是您想要的匹配項,并且它們周圍的空格將被拆分丟棄。在我看來,這個版本比試圖使用匹配更清楚地傳達了意圖。
regexp.Split()
\s+
regexp.Match()
^foo[:=]
strings.HasPrefix("foo:") || strings.HasPrefix("foo=")

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)
}
}
顯然,您需要修改此代碼以收集答案而不是打印它們。
如果您必須使用正則表達式,請使用其他答案。
- 3 回答
- 0 關注
- 118 瀏覽
添加回答
舉報