0

I have a validation like, String should contain at least one alphabet, or number. It may contain _ or - as optional character in between. The string should start and end with an alphabet or a number. I tried using many Regex, but I can't achieve this. Here is my RegEx code :

public static boolean isValidURL(String inputString) {
    try {
        boolean isValid = true;
        Pattern letter = Pattern.compile("[a-zA-z0-9]");
        String restPattern = "^[a-zA-Z0-9]+[a-zA-Z0-9_\\-\\s]?[a-zA-Z0-9]+$";
        Matcher hasLetter = letter.matcher(inputString);
        if (hasLetter.find()) {
            if (inputString.matches(restPattern)) {
                isValid = true;
            } else {
                isValid = false;
            }
        } else {
            isValid = false;
        }
        return isValid;
    } catch (Exception e) {
        throw e;
    }
}

And My Unit Test :

    assertEquals(true, Validator.isValidURL("res"));
    assertEquals(true, Validator.isValidURL("res_rer"));
    assertEquals(true, Validator.isValidURL("res-rer"));
    assertEquals(true, Validator.isValidURL("res232A"));
    assertEquals(true, Validator.isValidURL("232DFA"));
    assertEquals(true, Validator.isValidURL("23_323"));
    assertEquals(true, Validator.isValidURL("23"));
    assertEquals(true, Validator.isValidURL("A2s"));
    assertEquals(false, Validator.isValidURL("_"));
    assertEquals(false, Validator.isValidURL("-"));
    assertEquals(false, Validator.isValidURL("@"));
    assertEquals(false, Validator.isValidURL("@GR$"));
    assertEquals(false, Validator.isValidURL("_GR_"));
    assertEquals(false, Validator.isValidURL("GR_"));
    assertEquals(false, Validator.isValidURL("GR_"));
    assertEquals(true, Validator.isValidURL("s"));
    assertEquals(true, Validator.isValidURL("4"));

Last two assert getting failed. Please help me to solve this issue.

6
  • did you want to allow spaces? Commented Sep 19, 2014 at 4:32
  • 1
    The regex ends with a + quantifier so an extra character is needed at the end and since the last two strings are of length one it fails. Commented Sep 19, 2014 at 4:34
  • If I put optional quantifier ? ^[a-zA-Z0-9]?[a-zA-Z0-9_\\-\\s]?[a-zA-Z0-9]+$ The second assert itself getting failed. Commented Sep 19, 2014 at 4:35
  • Can there be multiple consecutive - and _? Commented Sep 19, 2014 at 4:37
  • Ya multiple consecutive Commented Sep 19, 2014 at 4:38

3 Answers 3

4

The below regex would allow one or more alphanumeric characters and also allows - or _ in-between the alphanumeric chars but not at the first or at the last.

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

DEMO

If you don't want consecutive _ or - then remove the + following the character class which was present inside the non-capturing group.

^[a-zA-Z0-9]+(?:[-_][a-zA-Z0-9]+)*$
Sign up to request clarification or add additional context in comments.

4 Comments

This is going to run into backtracking hell. Remove the optional quantifier ?
assertEquals(true, UtilityFunction.isValidURL("23___323")); This assert getting failed.
It may contains _ and - as optional char in between
just add a plus ^[a-zA-Z0-9]+(?:[-_]+[a-zA-Z0-9]+)*$ see regex101.com/r/gG9vW6/8
2

This should restrict the input to start and end with alphanumeric, and allow multiple consecutive - and _ within the input.

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

I turn all the quantifiers possessive (++ and *+ instead of + and *), to disallow backtracking.

1 Comment

@AvinashRaj: I develop the solution independently, but slower in answering the question, since I need to get all the assumptions by the OP straight.
0
^([a-zA-Z0-9]+[a-zA-Z0-9_\\-\\s]?[a-zA-Z0-9]+)|([a-zA-Z0-9])$

Just add one more or condition which accepting either alphabet or number

1 Comment

Correctness aside, this will do useless backtracking, since [a-zA-Z0-9_\\-\\s]? is optional, and you have [a-zA-Z0-9]+[a-zA-Z0-9]+ in a row.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.