【问题标题】:Regex to match strings that do not start with www in golang正则表达式匹配golang中不以www开头的字符串
【发布时间】:2019-03-09 22:42:55
【问题描述】:

我有以下正则表达式^http:\/\/(?!www\.)(.*)$

预期行为:

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

看起来golang 不支持负前瞻。如何重写此 RegEx 以在 golang 上工作?

更新

我没有使用 golang 编码,我使用的是Traefik,它接受正则表达式(golang 风格)作为配置值,所以基本上我有这个:

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

我想要的是始终将 www. 添加到 URL,但如果 URL 已经包含它,则 NOT,否则它将变为 www.www。 *

【问题讨论】:

  • 我对golang一无所知,这就是为什么这是一条评论,但你不能在if语句中匹配/^http:\/\/www\./,如果不匹配,请查找http://example.com
  • 更多信息请参考以下link
  • 我有同样的问题,我使用 re2 作为正则表达式引擎,没有 Golang 的完整表达能力(Terraform 的 regex() 函数。)尝试在 Terraform 0.13 中使用变量验证以确保用户不'不传递以某些单词开头或结尾的字符串——即,正则表达式不匹配 string(不仅仅是字符)。

标签: regex go traefik


【解决方案1】:

如果您真的想手动创建负前瞻,则需要在正则表达式中排除所有可能的w

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

此正则表达式允许在example.com 之前带有点的任何单词,除非该单词只是www。它通过允许任何不以w 开头的单词来实现这一点,或者,如果它以w 开头,那么它要么只是w,要么后跟非w 和其他东西。如果它以两个w 开头,那么它必须要么就是那个,要么后跟一个非w。如果它以www 开头,它必须后跟一些东西。

Demo

澄清使这变得容易得多。方法是始终(可选)匹配www.,然后始终将其放回替换中:

搜索:

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

替换:

http://www.$1

Demo 2

【讨论】:

  • 它部分工作。问题是我需要捕获 http:// 之后的任何域名,不包括“www”。
  • 此外,匹配的文本应该在第一个捕获组 ($1) 上。你认为有可能实现吗?
  • 总是匹配www. 然后无论如何都放回去怎么样?我会在上面更新我的答案
  • 天才!谢谢! :D
【解决方案2】:

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)
        }
    }
}

【讨论】:

  • 其实我并没有直接使用 golang,所以我不能这样做——我需要在 Traefik (traefik.io) 配置中指定一个 RegEx(golang 风格)。
猜你喜欢
  • 2014-08-15
  • 2012-02-23
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 2016-07-12
  • 2019-10-15
  • 2015-04-27
相关资源
最近更新 更多