1

I'm trying to create a Regex String with the following rules

  1. The username is between 4 and 25 characters.
  2. It must start with a letter.
  3. It can only contain letters, numbers, and the underscore character.
  4. It cannot end with an underscore character.

when it meets this criterion I want the output to be true otherwise false, but I only get false for my test cases, here is my code

public class Profile {
    public static String username(String str) {


        String regularExpression = "^[a-zA-Z][a-zA-Z0-9_](?<=@)\\w+\\b(?!\\_){4,25}$";

        if (str.matches(regularExpression)) {
            str = "true";
        }
        else if (!str.matches(regularExpression)) {
            str = "false";

        }
        return str;
    }

Main class

Profile profile = new profile();

Scanner s = new Scanner(System.in);
        System.out.print(profile.username(s.nextLine()));

input

"aa_"
"u__hello_world123"

output

false
false

Fixed: thanks to everyone who contributed

bobble bubble
  • 16,888
  • 3
  • 27
  • 46
Plus Ultra
  • 59
  • 1
  • 9

2 Answers2

3

You can use

^[a-zA-Z][a-zA-Z0-9_]{3,24}$(?<!_)
^[a-zA-Z]\w{3,24}$(?<!_)
^[a-zA-Z][a-zA-Z0-9_]{2,23}[a-zA-Z0-9]$
^\p{Alpha}[a-zA-Z0-9_]{2,23}\p{Alnum}$

See the regex demo.

Details:

  • ^ - start of string
  • [a-zA-Z] - an ASCII letter
  • [a-zA-Z0-9_]{3,24} / \w{3,24} - three to twenty four ASCII letters, digits or underscores
  • $ - end of string
  • (?<!_) - a negative lookbehind that makes sure there is no _ (at the end of string).

Note that {3,24} is used and not {4,25} because the first [a-zA-Z] pattern already matches a single char.

Usage:

public static String username(String str) {
    return Boolean.toString( str.trim().matches("[a-zA-Z]\\w{3,24}$(?<!_)") );
    // return Boolean.toString( str.trim().matches("\\p{Alpha}[a-zA-Z0-9_]{2,23}\\p{Alnum}") );
    // return Boolean.toString( str.trim().matches("[a-zA-Z][a-zA-Z0-9_]{2,23}[a-zA-Z0-9]") );
}

See Java demo:

import java.util.*;
import java.util.regex.*;

class Ideone
{
    public static String username(String str) {
        return Boolean.toString( str.trim().matches("[a-zA-Z]\\w{3,24}$(?<!_)") );
    }
    public static void main (String[] args) throws java.lang.Exception
    {
        System.out.println(username("u__hello_world123")); // => true
        System.out.println(username("aa_")); // => false
    }
}
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • thanks, I still get false for both cases, is it something that has to do with my code? – Plus Ultra Nov 02 '22 at 13:27
  • @PlusUltra I suggest trimming the line first, then check. Note that in `matches`, the first anchor is redundant since the whole string must match the regex. – Wiktor Stribiżew Nov 02 '22 at 13:33
  • Same behavior can be archieved without any lookbehind to be more readable: `^[a-zA-Z][a-zA-Z0-9_]{2,23}[a-zA-Z0-9]$` – berse2212 Nov 02 '22 at 13:39
  • thanks but still not working, it switched from false to true – Plus Ultra Nov 02 '22 at 13:51
  • If you literally input `"u__hello_world123"` in the console it results in false because of the quotation marks. They are not necessary since the input on the console is always interpreted as a string. When omitting them works perfectly fine for me. If that's not the case for you, you need to post more of your code. – berse2212 Nov 02 '22 at 14:13
  • @PlusUltra I added testing demo code to the answer, please check. Note that trimming helps get rid of any trailing line breaks you may get when scanning for lines. It should work. – Wiktor Stribiżew Nov 02 '22 at 14:22
0

Sounds like \p{L} any letter at the start, \w word characters between and \p{Alnum} in the end.

(?U)^\p{L}\w{2,23}\p{Alnum}$

As a Java String:

final String regex = "(?U)^\\p{L}\\w{2,23}\\p{Alnum}$";

See this demo at regex101 - Thank you @Thefourthbird for providing a Java demo at ideone.com


The (?U) modifier will turn on unicode support for predefined character classes, e.g. for \w. Instead of the embedded flag also Pattern.UNICODE_CHARACTER_CLASS can be used to enable.

bobble bubble
  • 16,888
  • 3
  • 27
  • 46