0

I'm having trouble converting this regex to something Golang supports. Could I get some help? It's originally from this SO question.

^(?=.{1,24}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+(?<![_.])$

Here's the criteria:

  1. Only contains alphanumeric characters, underscore and dot.
  2. Underscore and dot can't be at the end or start of a username (e.g _username / username_ / .username / username.).
  3. Underscore and dot can't be next to each other (e.g user_.name).
  4. Underscore or dot can't be used multiple times in a row (e.g user__name / user..name).
aroooo
  • 4,726
  • 8
  • 47
  • 81

1 Answers1

3

I don't have any experience with Go, so perhaps someone could come up with a better solution.
Here are the two options I found:

1. Write a regex that covers everything except the length restriction

You can use something like this:

^(?:[a-zA-Z0-9]+[._]?[a-zA-Z0-9]+)+$

Regex101 demo.

And you can use len to check for the string length. Here's a full example:

func main() { 
    var re = regexp.MustCompile(`(?m)^(?:[a-zA-Z0-9]+[._]?[a-zA-Z0-9]+)+$`)
    var str = `username
user_name
user.name
user.name_123
username$$$
_username
username_
user_.name
user._name
user__name
user..name
VeryLongUserNameThatExceedsTheLimit
`
    for i, match := range re.FindAllString(str, -1) {
        if len(match) <= 24 {fmt.Println(match, "found at index", i)}
    }
}

Output:

username found at index 0
user_name found at index 1
user.name found at index 2
user.name_123 found at index 3

Test it online.


2. Use a third-party engine

I found this .NET-based engine which should support Lookarounds. If the previous solution doesn't work for you, you may look into this. Note that the author of that engine recommends using the built-in engine whenever possible:

You'll likely be better off with the RE2 engine from the regexp package and should only use this if you need to write very complex patterns or require compatibility with .NET.