Is there a way to match everything except a constant string using Go.Regexp?
Golang intentionally leaves this feature out as there is no way to implement it in O(n) time to satisfy the constraints of a true Regular Expression according to Russ Cox:
The lack of generalized assertions, like the lack of backreferences, is not a statement on our part about regular expression style. It is a consequence of not knowing how to implement them efficiently. If you can implement them while preserving the guarantees made by the current package regexp, namely that it makes a single scan over the input and runs in O(n) time, then I would be happy to review and approve that CL. However, I have pondered how to do this for five years, off and on, and gotten nowhere.
It looks like the best way to do this is to manually check the match after as JimB mentions above.
The anything/anything/somestring
should not be expressed as \/.*\/.*\/(.*)
. The first .*
matches up to the last but one /
in the string. You need to use a negated character class [^/]
(not the /
should not be escaped in Go regex).
Since RE2 that Go uses does not support lookaheads, you need to capture (as JimB mentions in the comments) all three parts you are interested in, and after checking the capture group #1 value, decide what to return:
package main
import (
"fmt"
"regexp"
)
func main() {
s := "anything/anything/somestring"
r := regexp.MustCompile(`^[^/]+/[^/]+/(.*)`)
val := r.FindStringSubmatch(s)
// fmt.Println(val[1]) // -> somestring
if len(val) > 1 && val[1] != "somestring" { // val has more than 1 element and is not equal to somestring?
fmt.Println(val[1]) // Use val[1]
} else {
fmt.Println("No match") // Else, report no match
}
}
See the Go demo