dougu4027
2017-02-28 17:42
浏览 83
已采纳

是否可以使用Go.Regexp匹配除常量字符串以外的所有内容?

I have found many similar questions that do not work with the Go regex syntax.

The string that I am attempting to match against is in the form of anything/anything/somestring. With the pattern \/.*\/.*\/(.*), I will match somestring, but I am trying to match anything except strings that contain somestring.

Most answers propose using something like \/.*\/.*\/((?!somestring).*), however in golang regexp I get: ? The preceding token is not quantifiable.

For clarification: /test/test/MATCH would produce a match while /test/test/somestring would not. Is this possible with the (limited) Go regex syntax?

图片转代码服务由CSDN问答提供 功能建议

我发现许多类似的问题使用正则表达式语法

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

大多数答案建议使用类似 \ /.* \ /.* \ /((?! somestring)。*) ,但是在golang regexp中,我得到:? 前面的令牌是不可量化的

为澄清起见: / test / test / MATCH 将产生匹配项,而 / test / test / somestring 不会。 (受限制的)Go regex语法有可能吗?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • douwen8424 2017-03-02 09:36
    已采纳

    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

    点赞 评论
  • doumangzhen7204 2017-02-28 18:04

    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.

    点赞 评论

相关推荐 更多相似问题