有没有办法使用Go.Regexp匹配除常量字符串之外的所有内容?

时间:2017-02-28 17:42:18

标签: regex go

我发现许多类似的questionsGo regex syntax不兼容。

我尝试匹配的字符串采用isName()的形式。使用模式ObservableValue,我将匹配anything/anything/somestring,但我尝试匹配除包含\/.*\/.*\/(.*)的字符串之外的任何内容。

大多数答案建议使用类似somestring的内容,但是在golang regexp中,我得到:somestring

澄清:\/.*\/.*\/((?!somestring).*)会产生匹配,? The preceding token is not quantifiable则不会。这是否可以使用(有限的)Go正则表达式语法?

3 个答案:

答案 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)之类的方法来解决您的问题。