Golang регулярное выражение нескольких совпадений с `ReplaceAllString` - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь написать несколько регулярных выражений, которые сопоставляют и разделяют строки, которые выглядят как версии программного обеспечения (но на самом деле это не так, поэтому, например, некоторые операции синтаксического анализа не будут работать). У меня возникли проблемы с сопоставлением частей входной строки, которые я называю «префикс» и «суффикс».

Вывод, который я получаю из следующего, странный ..

// 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 голосов
/ 21 января 2019

Учитывая ваши образцы, это должно быть действительно легко.Я написал следующий код в верхней части моей головы.Возможно, он даже не скомпилируется, но вы должны понять:

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_PkgbasePattern и Test_MkParser_Dependency здесь:

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

Это может легко стать сложным.Вот почему вы должны написать тест для каждого интересного случая, с самого начала.

0 голосов
/ 21 января 2019

Regexp - неподходящий инструмент для этой простой задачи, потому что он медленный, трудный для чтения и, как показывает этот вопрос, трудно рассуждать. По тем же причинам 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)
}

См. ссылка на игровую площадку .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...