How to Validate Usernames With Regex in Java

The challenge

Write a simple regex to validate a username. Allowed characters are:

  • lowercase letters,
  • numbers,
  • underscore

Length should be between 4 and 16 characters (both included).

The solution in Java code

Option 1:

public class PasswordValidation {
  public static boolean validateUsr(String s) {
    return s.matches("[a-z_\\d]{4,16}");
  }
}

Option 2:

import java.util.regex.Pattern;
public class PasswordValidation {
  private static final Pattern usernamePattern = 
      Pattern.compile("[a-z0-9_]{4,16}");
  public static boolean validateUsr(String s) {
    return usernamePattern.matcher(s).matches();
  }
}

Option 3:

public class PasswordValidation {
  public static boolean validateUsr(String s) {
    return s.matches("[\\p{Ll}\\d\\_]{4,16}");
  }
}

Test cases to validate our solution

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;

public class SolutionTest {
    @Test
    public void basicTests() {
        assertEquals(true, PasswordValidation.validateUsr("regex"));
        assertEquals(false, PasswordValidation.validateUsr("a"));
        assertEquals(false, PasswordValidation.validateUsr("Hass"));
        assertEquals(false, PasswordValidation.validateUsr("Hasd_12assssssasasasasasaasasasasas"));
        assertEquals(false, PasswordValidation.validateUsr(""));
        assertEquals(true, PasswordValidation.validateUsr("____"));
        assertEquals(false, PasswordValidation.validateUsr("012"));
        assertEquals(true, PasswordValidation.validateUsr("p1pp1"));
        assertEquals(false, PasswordValidation.validateUsr("asd43 34"));
        assertEquals(true, PasswordValidation.validateUsr("asd43_34"));
    }
    
    @Test
    public void randomTests() {
      for (int i=1; i<201;i++) {
        String testString = makeWord(0,20);
        assertEquals("Test №"+i+" with string => "+testString, sollution(testString), PasswordValidation.validateUsr(testString));
      }
    }
    
    private boolean sollution(String str) {
      return str.matches("[a-z_\\d]{4,16}");
    }
    
    private String makeWord(int min, int max) {
      StringBuilder sb = new StringBuilder();
      String possible = "abcdefghijklmnopqrstuvwxyz_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_ 0123456789";
      int length = (int)Math.ceil((Math.random() * max) + min);
    
      for(int i = 0; i < length; i++) {
          sb.append(possible.charAt((int)Math.floor(Math.random() * possible.length())));
      }
    
      return sb.toString();
    }
}