Go: Replace String with Regular Expression Callback
February 17, 2016Go has many tools for regular expressions available in the default regex package. Let's see if you can pick up the pattern:
- PHP: preg_replace_callback($pattern, $callback, $subject)
- Ruby: subject.gsub(pattern) {|match| callback}
- Python: re.sub(pattern, callback, subject)
- JavaScript: subject.replace(pattern, callback)
- Go: ...oh noes!
All the individual mechanics that need to come together exist in the Go regex
package but they need to be strung together:
import "regexp"
func ReplaceAllGroupFunc(re *regexp.Regexp, str string, repl func([]string) string) string {
result := ""
lastIndex := 0
for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) {
groups := []string{}
for i := 0; i < len(v); i += 2 {
groups = append(groups, str[v[i]:v[i+1]])
}
result += str[lastIndex:v[0]] + repl(groups)
lastIndex = v[1]
}
return result + str[lastIndex:]
}
And here is a working example:
func main() {
str := "abc foo:bar def baz:qux ghi"
re := regexp.MustCompile("([a-z]+):([a-z]+)")
result := ReplaceAllGroupFunc(re, str, func(groups []string) string {
return groups[1] + "." + groups[2]
})
fmt.Printf("'%s'\n", result)
}
So finally, it can join the list!