3

I am trying to get a regex to retrieve alphanumeric OTP code (length of the code maybe dynamic i.e depending on user's choice) and must contain at least one digit.

I have tried the following regex : "[a-zA-z][0-9].[a-zA-z]"

But if a special character is there in the code it should result null instead it retrieves the characters before and after the special character which is not desired.

Some sample OTP-containing messages on which the regex is desired to work successfully:

  1. OTP is **** for txn of INR 78.90.
  2. **** is your one-time password.
  3. Hi, Your OTP is ****.

Examples of Alphanumeric OTPs with at least one-digit:

  1. 78784
  2. aZ837
  3. 987Ny
  4. 19hd35
  5. fc82pl
Steve Vinoski
  • 19,847
  • 3
  • 31
  • 46
Shrimantee Roy
  • 317
  • 3
  • 10
  • You can check these links. https://stackoverflow.com/questions/336210/regular-expression-for-alphanumeric-and-underscores , https://stackoverflow.com/questions/5988228/how-to-create-a-regex-for-accepting-only-alphanumeric-characters/5988385 – Sambit Jul 31 '19 at 05:36

3 Answers3

3

It would be a bit difficult, maybe this expression might work with an i flag:

[a-z0-9]*\d[a-z0-9]*

or with word boundaries:

(?<=\b)[a-z0-9]*\d[a-z0-9]*(?=\b)

Test

import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "[a-z0-9]*\\d[a-z0-9]*";
final String string = "78784\n"
     + "aZ837\n"
     + "987Ny\n"
     + "19hd35\n"
     + "fc82pl";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
final Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println("Full match: " + matcher.group(0));
    for (int i = 1; i <= matcher.groupCount(); i++) {
        System.out.println("Group " + i + ": " + matcher.group(i));
    }
}

The expression is explained on the top right panel of regex101.com, if you wish to explore/simplify/modify it, and in this link, you can watch how it would match against some sample inputs, if you like.

Emma
  • 27,428
  • 11
  • 44
  • 69
  • 1
    I'd encapsulate it with lookbehind (?<=\b) and lookahead (?=\b) just to avoid some false positives, but otherwise it look good. – Ján Stibila Jul 31 '19 at 11:36
1

Try this one

[0-9a-zA-Z]*[0-9]+[0-9a-zA-Z]*

This evaluates your desired result.

I have tested this in this site

sarwar026
  • 3,821
  • 3
  • 26
  • 37
1

Your regex is almost correct. It should be \b[a-zA-z]*[0-9]+[a-zA-z0-9]*\b.

csabinho
  • 1,579
  • 1
  • 18
  • 28