Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex for a pattern XXYYZZ

Tags:

java

string

regex

I want to validate a string which should follow the pattern XXYYZZ where X, Y, Z can be any letter a-z, A-Z or 0-9.

Example of valid strings:

RRFFKK
BB7733
WWDDMM
5599AA

Not valid:

555677
AABBCD

For now I am splitting the string using the regex (?<=(.))(?!\\1) and iterating over the resulting array and checking if each substring has a length of 2.

String str = "AABBEE";
boolean isValid = checkPattern(str);

public static boolean checkPattern(String str) {
   String splited = str.split("(?<=(.))(?!\\1)");
   for (String s : splited) {
       if (s.length() != 2) {
         return false;
       }
   }
   return true;
}

I would like to replace my way of checking with String#matches and get rid of the loop, but can't come up with a valid regex. Can some one help what to put in someRegex in the below snippet?

public static boolean checkPattern(String str) {
    return str.matches(someRegex);
}
like image 576
nopens Avatar asked Dec 24 '20 15:12

nopens


People also ask

What is regular expression (regex)?

Regular expressions or commonly called as Regex or Regexp is technically a string (a combination of alphabets, numbers and special characters) of text which helps in extracting information from text by matching, searching and sorting.

How do you use regex on a phone number pattern?

To create a Regex object that matches the phone number pattern, enter the following into the interactive shell. Now the phoneNumRegex variable contains a Regex object. A Regex object’s search () method searches the string it is passed for any matches to the regex.

How do you use regex in Python for pattern matching?

Pattern matching in Python with Regex. You may be familiar with searching for text by pressing ctrl-F and typing in the words you’re looking for. Regular expressions go one step further: They allow you to specify a pattern of text to search for. Regular expressions, called regexes for short, are descriptions for a pattern of text.

How to compile a regex into a pattern?

The compile () method accepts the regex as a first argument. This class does not provide any public constructor. This method is used to compile the given regex into a pattern. This method creates a matcher for matching the pattern with the given string, which is inputted by a user. This method returns the representation of the string.


4 Answers

You can use

s.matches("(\\p{Alnum})\\1(?!\\1)(\\p{Alnum})\\2(?!\\1|\\2)(\\p{Alnum})\\3")

See the regex demo.

Details

  • \A - start of string (it is implicit in String#matches) - the start of string
  • (\p{Alnum})\1 - an alphanumeric char (captured into Group 1) and an identical char right after
  • (?!\1) - the next char cannot be the same as in Group 1
  • (\p{Alnum})\2 - an alphanumeric char (captured into Group 2) and an identical char right after
  • (?!\1|\2) - the next char cannot be the same as in Group 1 and 2
  • (\p{Alnum})\3 - an alphanumeric char (captured into Group 3) and an identical char right after
  • \z - (implicit in String#matches) - end of string.

RegexPlanet test results:

enter image description here

like image 138
Wiktor Stribiżew Avatar answered Oct 10 '22 15:10

Wiktor Stribiżew


Since you know a valid pattern will always be six characters long with three pairs of equal characters which are different from each other, a short series of explicit conditions may be simpler than a regex:

public static boolean checkPattern(String str) {
   return str.length() == 6 &&
          str.charAt(0) == str.chatAt(1) &&
          str.charAt(2) == str.chatAt(3) &&
          str.charAt(4) == str.chatAt(5) &&
          str.charAt(0) != str.charAt(2) &&
          str.charAt(0) != str.charAt(4) &&
          str.charAt(2) != str.charAt(4);
}
like image 34
Mureinik Avatar answered Oct 10 '22 16:10

Mureinik


Would the following work for you?

^(([A-Za-z\d])\2(?!.*\2)){3}$

See the online demo


  • ^ - Start string anchor.
  • (- Open 1st capture group.
    • ( - Open 2nd capture group.
      • [A-Za-z\d] - Any alphanumeric character.
      • ) - Close 2nd capture group.
    • \2 - Match exactly what was just captured.
    • (?!.*\2) - Negative lookahead to make sure the same character is not used elsewhere.
    • ) - Close 1st capture group.
  • {3} - Repeat the above three times.
  • $ - End string anchor.
like image 6
JvdV Avatar answered Oct 10 '22 15:10

JvdV


Well, here's another solution that uses regex and streams in combination.

  • It breaks up the pattern into groups of two characters.
  • keeps the distinct groups.
  • and returns true if the count is 3.
String[] data = { "AABBBB", "AABBCC", "AAAAAA","AABBAA", "ABC", "AAABCC",
        "RRABBCCC" };
String pat = "(?:\\G(.)\\1)+";
Pattern pattern = Pattern.compile(pat);

for (String str : data) {
    Matcher m = pattern.matcher(str);
    boolean isValid = m.results().map(MatchResult::group).distinct().count() == 3;
    System.out.printf("%8s  ->  %s%n",
            str, isValid ? "Valid" : "Not Valid");
}

Prints

  AABBBB  ->  Not Valid
  AABBCC  ->  Valid
  AAAAAA  ->  Not Valid
  AABBAA  ->  Not Valid
     ABC  ->  Not Valid
  AAABCC  ->  Not Valid
RRABBCCC  ->  Not Valid
like image 2
WJS Avatar answered Oct 10 '22 15:10

WJS