Golang正则表达式与`ReplaceAllString`多次匹配

时间:2019-01-21 06:38:17

标签: regex go

我正在尝试编写一些正则表达式,它们匹配并拉开看起来像软件版本的字符串(但是它们不是真的,因此,例如semver解析将无法工作)。我在匹配输入字符串的“前缀”和“后缀”部分时遇到了麻烦。

我从下面得到的输出很奇怪。

// Sample inputs:
// * '1.2.3-thing' (Prefix: '1.2.3', Suffix: '-thing')
// * '1.2.3+1' (Prefix: '1.2.3', Suffix: '+1')
// * '1.2.3' (Prefix: '1.2.3', Suffix: '')
// * '1' (Prefix: '1', Suffix: '')
// * '1-x' (Prefix: '1', Suffix: '-x')
// * '1-x-x' (Prefix: '1', Suffix: '-x-x')
// * '1.2.3-thing.1' (Prefix: '1.2.3', Suffix: '-thing.1')
// * '1.2-thing-1' (Prefix: '1.2', Suffix: '-thing-1')
// * 'k1.2.3-thing' (Prefix: 'k1.2.3', Suffix: '-thing')
// * 'k-thing-x' (Prefix: 'k', Suffix: '-thing-x')
//
func InspectVersionTag(tag string) {
    re := regexp.MustCompile(`^([^\-]+)([\-+].+)$`)
    suffix := ""
    if re.MatchString(tag) {
        tag = re.ReplaceAllString(tag, `$1`)
        suffix = re.ReplaceAllString(tag, `$2`)
    }
    fmt.Println(fmt.Sprintf("Prefix is: %s", tag))
    fmt.Println(fmt.Sprintf("Suffix is: %s", suffix))
}

// Current sample output
//
// Input: 1.2.3+1
// Prefix is: 1.2.3
// Suffix is: 1.2.3

2 个答案:

答案 0 :(得分:2)

给出您的样本,这应该真的很容易。我从头开始编写了以下代码。它甚至可能没有编译,但是您应该明白了:

func parseVersion(ver string) (prefix, suffix string) {
    parts := strings.SplitAfter(ver, "-", 2)
    if len(parts) == 1 {
        parts = strings.SplitAfter(ver, "+", 2)
    }
    if len(parts) == 1 {
        return ver, ""
    }
    return parts[0], parts [1]
}

您绝对应该在自动测试中列出所有示例,而不要发表评论。而且如果上面的代码没有帮助,那么您的示例还不够实际。

这是我解决类似问题的方法。在这里查看Test_MkParser_PkgbasePatternTest_MkParser_Dependency

https://github.com/rillig/pkglint/blob/master/mkparser_test.go

它很容易变得复杂。这就是为什么您应该从一开始就为每个有趣的案例编写测试。

答案 1 :(得分:0)

正则表达式是执行此简单任务的错误工具,因为它速度慢,难以阅读,并且正如该问题所指出的那样,难以推理。由于同样的原因,regexp对于几乎用于它的所有任务都是错误的工具。

对于您而言,您需要做的只是在分隔符上分开:-+

func InspectVersionTag(tag string) {
    var suffix string
    for _, sep := range []string{"-","+"} {
        if strings.Contains(tag, sep) {
            parts := strings.SplitN(tag, sep, 2)
            tag, suffix = parts[0], sep+parts[1]
            continue
        }
    }
    fmt.Printf("Prefix: %s Suffix: %s\n", tag, suffix)
}

请参见playground link