1 回答

TA貢獻(xiàn)2019條經(jīng)驗(yàn) 獲得超9個(gè)贊
您想要實(shí)現(xiàn)的是訪問(wèn)捕獲組。我更喜歡命名捕獲組,并且有一個(gè)非常簡(jiǎn)單的輔助函數(shù)可以處理這個(gè)問(wèn)題:
package main
import (
"fmt"
"regexp"
)
// Our example input
const input = "X-sync-status: done\r\n"
// We anchor the regex to the beginning of a line with "^".
// Then we have a fixed string until our capturing group begins.
// Within our capturing group, we want to have all consecutive non-whitespace,
// non-control characters following.
const regexString = `(?i)^X-sync-status: (?P<status>\w*)`
// We ensure our regexp is valid and can be used.
var syncStatusRegexp *regexp.Regexp = regexp.MustCompile(regexString)
// The helper function...
func namedResults(re *regexp.Regexp, in string) map[string]string {
// ... does the matching
match := re.FindStringSubmatch(in)
result := make(map[string]string)
// and puts the value for each named capturing group
// into the result map
for i, name := range re.SubexpNames() {
if i != 0 && name != "" {
result[name] = match[i]
}
}
return result
}
func main() {
fmt.Println(namedResults(syncStatusRegexp, input)["status"])
}
注意您當(dāng)前的正則表達(dá)式有些錯(cuò)誤,因?yàn)槟矔?huì)捕獲空格。使用當(dāng)前的正則表達(dá)式,結(jié)果將是“done”而不是“done”。
編輯:當(dāng)然,如果沒(méi)有正則表達(dá)式,您可以更便宜地做到這一點(diǎn):
fmt.Print(strings.Trim(strings.Split(input, ":")[1], " \r\n"))
Edit2我很好奇 split 方法便宜多少,因此我想出了非常粗略的方法:
package main
import (
"fmt"
"log"
"regexp"
"strings"
)
// Our example input
const input = "X-sync-status: done\r\n"
// We anchor the regex to the beginning of a line with "^".
// Then we have a fixed string until our capturing group begins.
// Within our capturing group, we want to have all consecutive non-whitespace,
// non-control characters following.
const regexString = `(?i)^X-sync-status: (?P<status>\w*)`
// We ensure our regexp is valid and can be used.
var syncStatusRegexp *regexp.Regexp = regexp.MustCompile(regexString)
func statusBySplit(in string) string {
return strings.Trim(strings.Split(input, ":")[1], " \r\n")
}
func statusByRegexp(re *regexp.Regexp, in string) string {
return re.FindStringSubmatch(in)[1]
}
[...]
和一個(gè)小基準(zhǔn):
package main
import "testing"
func BenchmarkRegexp(b *testing.B) {
for i := 0; i < b.N; i++ {
statusByRegexp(syncStatusRegexp, input)
}
}
func BenchmarkSplit(b *testing.B) {
for i := 0; i < b.N; i++ {
statusBySplit(input)
}
}
然后,我讓它們分別在 1 個(gè)、2 個(gè)和 4 個(gè)可用的 CPU 上運(yùn)行 5 次。恕我直言,結(jié)果非常有說(shuō)服力:
go test -run=^$ -test.bench=. -test.benchmem -test.cpu 1,2,4 -test.count=5
goos: darwin
goarch: amd64
pkg: github.com/mwmahlberg/so-regex
BenchmarkRegexp 5000000 383 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp 5000000 382 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp 5000000 382 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp 5000000 382 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp 5000000 384 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-2 5000000 384 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-2 5000000 382 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-2 5000000 384 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-2 5000000 382 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-2 5000000 382 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-4 5000000 382 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-4 5000000 382 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-4 5000000 380 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-4 5000000 380 ns/op 32 B/op 1 allocs/op
BenchmarkRegexp-4 5000000 377 ns/op 32 B/op 1 allocs/op
BenchmarkSplit 10000000 161 ns/op 80 B/op 3 allocs/op
BenchmarkSplit 10000000 161 ns/op 80 B/op 3 allocs/op
BenchmarkSplit 10000000 164 ns/op 80 B/op 3 allocs/op
BenchmarkSplit 10000000 165 ns/op 80 B/op 3 allocs/op
BenchmarkSplit 10000000 162 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-2 10000000 159 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-2 10000000 167 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-2 10000000 161 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-2 10000000 159 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-2 10000000 159 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-4 10000000 159 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-4 10000000 161 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-4 10000000 159 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-4 10000000 160 ns/op 80 B/op 3 allocs/op
BenchmarkSplit-4 10000000 160 ns/op 80 B/op 3 allocs/op
PASS
ok github.com/mwmahlberg/so-regex 61.340s
它清楚地表明,在拆分標(biāo)簽的情況下,實(shí)際使用拆分的速度是預(yù)編譯正則表達(dá)式的兩倍多。對(duì)于您的用例,我顯然會(huì)選擇使用 split。
- 1 回答
- 0 關(guān)注
- 100 瀏覽
添加回答
舉報(bào)