正则表达式匹配golang中不以www开头的字符串
Regex to match strings that do not start with www in golang
我有以下 RegEx ^http:\/\/(?!www\.)(.*)$
预期行为:
http://example.com - Match
http://www.example.com - Does not match
看起来 golang
不支持负前瞻。我如何重写此 RegEx 以在 golang
上工作?
更新
我没有使用 golang 进行编码,我使用的是接受正则表达式(golang 风格)作为配置值的 Traefik,所以基本上我有这个:
regex = "^https://(.*)$"
replacement = "https://www."
我想要的是始终将 www. 添加到 URL,但 NOT 如果 URL已经有了,不然就变成www.www.*
如果您真的一心想手动创建否定前瞻,则需要在正则表达式中排除所有可能的 w
:
^https?://(([^w].+|w(|[^w].*)|ww(|[^w].+)|www.+)\.)?example\.com$
此正则表达式允许在 example.com
之前带点的任何单词,除非该单词只是 www
。它通过允许任何不以 w
开头的单词来做到这一点,或者,如果它以 w
开头,则它要么只是 w
,要么后跟一个非 w
和其他东西。如果它以两个 w
开头,那么它必须是那个或后面跟一个非 w
。如果它以 www
开头,它 必须 后跟一些东西。
澄清使这变得容易得多。方法是始终(可选)匹配 www.
,然后始终将其放回替换中:
搜索:
^http://(?:www\.)?(.*)\b$
替换:
http://www.
Golang 使用 RE2 正则表达式引擎,doesn't support look arounds of any kind。
由于您正在处理 URL,因此您可以简单地解析它们并检查主机部分:
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)
}
}
}
我有以下 RegEx ^http:\/\/(?!www\.)(.*)$
预期行为:
http://example.com - Match
http://www.example.com - Does not match
看起来 golang
不支持负前瞻。我如何重写此 RegEx 以在 golang
上工作?
更新
我没有使用 golang 进行编码,我使用的是接受正则表达式(golang 风格)作为配置值的 Traefik,所以基本上我有这个:
regex = "^https://(.*)$"
replacement = "https://www."
我想要的是始终将 www. 添加到 URL,但 NOT 如果 URL已经有了,不然就变成www.www.*
如果您真的一心想手动创建否定前瞻,则需要在正则表达式中排除所有可能的 w
:
^https?://(([^w].+|w(|[^w].*)|ww(|[^w].+)|www.+)\.)?example\.com$
此正则表达式允许在 example.com
之前带点的任何单词,除非该单词只是 www
。它通过允许任何不以 w
开头的单词来做到这一点,或者,如果它以 w
开头,则它要么只是 w
,要么后跟一个非 w
和其他东西。如果它以两个 w
开头,那么它必须是那个或后面跟一个非 w
。如果它以 www
开头,它 必须 后跟一些东西。
澄清使这变得容易得多。方法是始终(可选)匹配 www.
,然后始终将其放回替换中:
搜索:
^http://(?:www\.)?(.*)\b$
替换:
http://www.
Golang 使用 RE2 正则表达式引擎,doesn't support look arounds of any kind。
由于您正在处理 URL,因此您可以简单地解析它们并检查主机部分:
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)
}
}
}