Go: Replace String with Regular Expression Callback
1 min readMar 12, 2016
Go has many tools for regular expressions available in the default regex package. However, 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 regexpackage but they need to be strung together:
import "regexp"func ReplaceAllStringSubmatchFunc(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 := ReplaceAllStringSubmatchFunc(re, str, func(groups []string) string {
return "(" + groups[1] + "->" + groups[2] + ")"
})
fmt.Printf("%s\n", result)
}abc (foo->bar) def (baz->qui) ghi
abc (foo->bar) def (baz->qui) ghi
So finally, it can join the list!
Originally published at http://elliot.land on March 12, 2016.