Соглашение об имени пользователя Github с использованием регулярных выражений - PullRequest
0 голосов
/ 06 ноября 2019

Я уже некоторое время пытаюсь преобразовать соглашение об имени пользователя Github с помощью регулярных выражений в Go, и я не смог этого сделать. Также длина имени пользователя не должна превышать более 39 символов .

Ниже приведено соглашение об имени пользователя от Github

Имя пользователя может содержать только буквенно-цифровые символы или одиночные дефисыи не может начинаться или заканчиваться дефисом.

и для длины

Имя пользователя слишком длинное (максимум 39 символов).

Вот код, который я написал. Вы можете проверить здесь, на Игровая площадка Go

package main

import (
    "fmt"
    "regexp"
)

func main() {
    usernameConvention := "^[a-zA-Z0-9]*[-]?[a-zA-Z0-9]*$"

    if re, _ := regexp.Compile(usernameConvention); !re.MatchString("abc-abc") {
        fmt.Println("false")
    } else {
        fmt.Println("true")
    }
}

В настоящее время я могу достичь следующих целей:

a-b // true - Working!
-ab // false - Working!
ab- // false - Working!
0-0 // true - Working!

Но проблема в том, что я не могуНе могу найти шаблон регулярного выражения, который должен работать для следующего сценария:

a-b-c // false - Should be true

Также он должен быть в пределах 39 символов, которые я нашел, что мы могли бы использовать {1,38}, но я не знаю, гдеименно я должен добавить это в шаблоне регулярных выражений.

1 Ответ

1 голос
/ 06 ноября 2019

В регулярном выражении Go RE2 вы не можете использовать обходные пути, поэтому проверка предела длины может выполняться только с другим регулярным выражением или с регулярной проверкой длины строки.

Полностью не-регулярный подход ( демо ):

package main

import (
    "fmt"
    "strings"
)
func IsAlnumOrHyphen(s string) bool {
    for _, r := range s {
        if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') && (r < '0' || r > '9') && r != '-' {
            return false
        }
    }
    return true
}

func main() {
    s := "abc-abc-abc"
    if  len(s) < 40 && len(s) > 0 && !strings.HasPrefix(s, "-") && !strings.Contains(s, "--") && !strings.HasSuffix(s, "-") && IsAlnumOrHyphen(s) {
        fmt.Println("true")
    } else {

        fmt.Println("false")
    }
}

Подробности

  • len(s) < 40 && len(s) > 0- ограничение длины, допускается от 1 до 39 символов
  • !strings.HasPrefix(s, "-") - не должно начинаться с -
  • !strings.Contains(s, "--") - не должно содержать --
  • !strings.HasSuffix(s, "-") - не должен заканчиваться -
  • IsAlnumOrHyphen(s) - может содержать только буквенно-цифровые символы ASCII и дефисы.

Для подхода с частичным регулярным выражением см. this Goдемо :

package main

import (
    "fmt"
    "regexp"
)

func main() {
    usernameConvention := "^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$"
    re,_ := regexp.Compile(usernameConvention)
    s := "abc-abc-abc"
    if len(s) < 40 && len(s) > 0 && re.MatchString(s) {
        fmt.Println("true")
    } else {

        fmt.Println("false")
    }
}

Здесь регулярное выражение ^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$ соответствует

  • ^ - начало строки
  • [a-zA-Z0-9]+ - 1 илибольше буквенно-цифровых символов ASCII
  • (?:-[a-zA-Z0-9]+)* - 0 или более повторений -, а затем 1 или более буквенно-цифровых символов ASCII
  • $ - конец строки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...