duanlu1908
2018-10-04 13:48
浏览 701
已采纳

正则表达式匹配golang中不以www开头的字符串

I have the following RegEx ^http:\/\/(?!www\.)(.*)$

Expected behavior:

http://example.com - Match
http://www.example.com - Does not match

It looks like golang does not support negative lookahead. How can I rewrite this RegEx to work on golang?

UPDATE

I'm not coding using golang, I'm using Traefik that accepts a Regex (golang flavor) as a config value, so basically I have this:

regex = "^https://(.*)$"
replacement = "https://www.$1"

What I want is to always add www. to the URL, but NOT if the URL has it already, otherwise it would become www.www.*

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

我有以下RegEx ^ http:\ / \ /(?! www \。)(。 *)$

预期的行为:

  http://example.com-匹配
http:// www  .example.com-不匹配
   
 
 

golang 似乎不支持否定超前。 我如何重写此RegEx以在 golang 上工作?

更新

我是 我没有使用golang进行编码,因此我使用的是 Traefik ,它接受Regex(golang风格)作为配置值,因此基本上 我有这个:

  regex =“ ^ https://(。*)$” 
replacement =“ https://www.$1” 
    
 
 

我想要的是始终在URL中添加 www。,但是如果URL中已经包含 NOT ,则为 NOT ,否则 成为 www.www。*

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

2条回答 默认 最新

  • doukengsha9472 2018-10-04 14:02
    已采纳

    If you're really bent on creating a negative lookahead manually, you will need to exclude all possible w in the regexp:

    ^https?://(([^w].+|w(|[^w].*)|ww(|[^w].+)|www.+)\.)?example\.com$
    

    This regexp allows any word with a dot before example.com, unless that word is just www. It does so by allowing any word that does not start with w, or, if it starts with w it is either just that w or followed by a non-w and other stuff. If it starts with two w, then it must be either just that or followed by a non-w. If it starts with www, it must be followed by something.

    Demo

    The clarification makes this much much easier. The approach is to always (optionally) match www. and then to put that back in the replacement always:

    Search:

    ^http://(?:www\.)?(.*)\b$
    

    Replace:

    http://www.$1
    

    Demo 2

    点赞 评论
  • duanji7182 2018-10-04 15:33

    Golang uses the RE2 regex engine, which doesn't support look arounds of any kind.

    Since you are dealing with URLs, you can simply parse them and inspect the host part:

    package main
    
    import (
        "net/url"
        "strings"
        "testing"
    )
    
    func Match(s string) bool {
        u, err := url.Parse(s)
        switch {
        case err != nil:
            return false
        case u.Scheme != "http":
            return false
        case u.User != nil:
            return false
        }
    
        return !strings.HasPrefix(u.Host, "www.")
    }
    
    func TestMatch(t *testing.T) {
        testCases := []struct {
            URL  string
            Want bool
        }{
            {"http://example.com", true},
            {"http://wwwexample.com", true},
            {"http://www.example.com", false},
            {"http://user@example.com", false},
            {"http://user@www.example.com", false},
            {"www.example.com", false},
            {"example.com", false},
        }
    
        for _, tc := range testCases {
            if m := Match(tc.URL); m != tc.Want {
                t.Errorf("Match(%q) = %v; want %v", tc.URL, m, tc.Want)
            }
        }
    }
    
    点赞 评论

相关推荐 更多相似问题