问题
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.*
回答1:
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
回答2:
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)
}
}
}
来源:https://stackoverflow.com/questions/52648425/regex-to-match-strings-that-do-not-start-with-www-in-golang