我发现许多类似的questions与Go regex syntax不兼容。
我尝试匹配的字符串采用isName()
的形式。使用模式ObservableValue
,我将匹配anything/anything/somestring
,但我尝试匹配除包含\/.*\/.*\/(.*)
的字符串之外的任何内容。
大多数答案建议使用类似somestring
的内容,但是在golang regexp中,我得到:somestring
。
澄清:\/.*\/.*\/((?!somestring).*)
会产生匹配,? The preceding token is not quantifiable
则不会。这是否可以使用(有限的)Go正则表达式语法?
答案 0 :(得分:2)
Golang故意遗弃此功能,因为无法在O(n)时间内实现它以满足真正的正则表达式according to Russ Cox的约束:
缺乏广泛的断言,如缺乏反向引用, 我们不是关于正则表达式的声明。它是 不知道如何有效实施它们的结果。如果 你可以实现它们,同时保留由 当前包regexp,即它进行单次扫描 输入并在O(n)时间运行,然后我很乐意回顾和 批准CL。但是,我考虑过如何为五个人做这个 岁月,断断续续,无处可去。
看起来最好的方法是在JimB上面提到之后手动检查匹配。
答案 1 :(得分:2)
anything/anything/somestring
不应表示为\/.*\/.*\/(.*)
。第一个.*
匹配字符串中的最后一个/
。你需要使用一个否定的字符类[^/]
(不应该在Go正则表达式中转义/
)。
由于Go使用的RE2不支持前瞻,因此您需要捕获(作为JimB mentions in the comments)您感兴趣的所有三个部分,并在检查捕获组#1值后,决定返回什么:
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
}
}
请参阅Go demo
答案 2 :(得分:0)
有regexp2为Go实现了功能丰富的RegExp引擎,它没有像内置regexp
包那样的恒定时间保证,但是它允许回溯。然后,您可以使用类似(?!somestring)
之类的方法来解决您的问题。