我同意在功能內部訪問捕獲組是理想的,我認爲這不可能與regexp.ReplaceAllFunc
。 只有在我腦海中的東西現在如何看待與功能要做到這一點是這樣的:
package main
import (
"fmt"
"regexp"
)
func main() {
body := []byte("Visit this page: [PageName] [OtherPageName]")
search := regexp.MustCompile("\\[[a-zA-Z]+\\]")
body = search.ReplaceAllFunc(body, func(s []byte) []byte {
m := string(s[1 : len(s)-1])
return []byte("<a href=\"/view/" + m + "\">" + m + "</a>")
})
fmt.Println(string(body))
}
編輯
還有就是我知道該怎麼做你想做的另一種方式。首先您需要知道的是,您可以使用語法(?:re)
指定非捕獲組,其中re
是您的正則表達式。這不是必需的,但會減少無關匹配的數量。
接下來要知道的是regexp.FindAllSubmatcheIndex。它會返回切片,其中每個內部切片表示範圍全部子匹配給定正則表達式的匹配。
有了這個兩件事情,你可以構造有些通用的解決方案:
package main
import (
"fmt"
"regexp"
)
func ReplaceAllSubmatchFunc(re *regexp.Regexp, b []byte, f func(s []byte) []byte) []byte {
idxs := re.FindAllSubmatchIndex(b, -1)
if len(idxs) == 0 {
return b
}
l := len(idxs)
ret := append([]byte{}, b[:idxs[0][0]]...)
for i, pair := range idxs {
// replace internal submatch with result of user supplied function
ret = append(ret, f(b[pair[2]:pair[3]])...)
if i+1 < l {
ret = append(ret, b[pair[1]:idxs[i+1][0]]...)
}
}
ret = append(ret, b[idxs[len(idxs)-1][1]:]...)
return ret
}
func main() {
body := []byte("Visit this page: [PageName] [OtherPageName][XYZ] [XY]")
search := regexp.MustCompile("(?:\\[)([a-zA-Z]+)(?:\\])")
body = ReplaceAllSubmatchFunc(search, body, func(s []byte) []byte {
m := string(s)
return []byte("<a href=\"/view/" + m + "\">" + m + "</a>")
})
fmt.Println(string(body))
}
是的,這是我想到的解決方法。不過,使用捕獲組將會是一個更優雅的解決方案。太糟糕了,我們不能用'ReplaceAllFunc()'來做到這一點...... –