2017-02-28 121 views
1

我发现许多类似的questions不适用于Go regex syntax有没有一种方法可以匹配除了使用Go.Regexp的常量字符串以外的所有内容?

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

大多数答案建议使用类似\/.*\/.*\/((?!somestring).*),但是在golang正则表达式中我得到:? The preceding token is not quantifiable

澄清:/test/test/MATCH会产生匹配,而/test/test/somestring不会。这可能与(有限)Go正则表达式语法?

+0

看起来几乎一切都是_NOT SUPPORTED_。它真的是一个正则表达式引擎吗?无论如何,断言不可用(它说),所以'(?!somestring)',这是你所需要的,已经不存在了。唯一的解决方法是在while循环中使用正则表达式'\ /.* \ /.* \ /(。*)'。每个匹配,字符串比较组1与'somestring'。 – sln

+2

RE2(Go实现)不支持lookarounds。只需自己检查一下submatches。 – JimB

回答

1

anything/anything/somestring不应该表示为\/.*\/.*\/(.*)。第一个.*与字符串中的最后一个相匹配,但一个/。您需要使用否定字符类[^/](不应该在Go正则表达式中转义/)。

由于RE2是Go使用不支持向前看符号,你需要捕捉(为JimB mentions in the comments所有三个部分你有兴趣,并检查捕获组#1的值之后,决定如何返回:

包主要

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

0

Golang故意留下这个功能了,因为没有办法实现它在O(n)的时间,以满足真正的正则表达式according to Russ Cox的约束:

缺乏普遍断言,像缺乏的反向引用, 不是关于正则表达式风格的声明。由于不知道如何有效地实现它们,所以它是 。如果 可以实现它们,同时保留 当前软件包正则表达式的保证,即它对 输入进行单次扫描并在O(n)时间内运行,那么我会很乐意审查并且 同意CL 。但是,我已经思考了如何在五年内完成这个工作,不管什么时候开始。

看起来最好的方法是在JimB上面提到的手动检查匹配之后。

相关问题