Home > Software design >  Regex match group not working even if .find() and matches() were already called
Regex match group not working even if .find() and matches() were already called

Time:12-14

I've already tried adding the matcher.find() and matcher.matches() in order to query matching string values, but still its not working.

I am trying to have 3 group patterns to match, and for my example here, I want to match and find group 1 of pattern enclosed in the first round parenthesis.

public class RegexGroupExample2 {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("(^0\\d{10})(^\\d{10})(^63\\d{10})");
          String input = "09187654321";
          Matcher m = pattern.matcher(input);
          m.find();
          // m.matches();
          String grp1 = m.group(1);
          System.out.println("Group 1 "   grp1);
          System.out.println(input);
        }
    }

Why is the grp1 not being retrieved?, afaik this code should work as I already called .find() or .matches() which is required for using .group() methods.

For reference, I'm trying to apply the accepted answer here that uses matcher.group(int) to match strings

Attached below is the code that I will have if I dont implement Java Match Group feature just like in the answer which is in link above, I would have at least 5 declaration for each patterns and matchers instead of just one Pattern and Matchers to determine what patterns matched.

private String getInputtedDigitsLocal(final String mobileNumber) {
        String extractedMobileNumber = "_";
//        final Pattern pattern = Pattern.compile("(^0\\d{10}$)||(^\\d{10}$)||^\\ 63\\d{10}$||(^63\\d{10}$)");
//        final Matcher matcher = pattern.matcher(mobileNumber);

        final Pattern pattern1 = Pattern.compile("^0\\d{10}$");
        final Pattern pattern2 = Pattern.compile("^\\d{10}$");
        final Pattern pattern3 = Pattern.compile("^\\ 63\\d{10}$");
        final Pattern pattern4 = Pattern.compile("^63\\d{10}$");
        final Matcher matcher1 = pattern1.matcher(mobileNumber);
        final Matcher matcher2 = pattern2.matcher(mobileNumber);
        final Matcher matcher3 = pattern3.matcher(mobileNumber);
        final Matcher matcher4 = pattern4.matcher(mobileNumber);
        if (matcher1.find()) {
            // test Data 0918765321
            extractedMobileNumber = mobileNumber;
        } else if (matcher2.find()) {
            // test Data 9187654321
            extractedMobileNumber = "0"   mobileNumber;

        } else if (matcher3.find()) {
            //test Data  639187654321
            extractedMobileNumber=mobileNumber "Draft";
        } else if (matcher4.find()) {
            //test Data 639187654321
            extractedMobileNumber=mobileNumber "Draft";
        } else {
            extractedMobileNumber="NOT SUPPORTED FORMAT";
        }


        return extractedMobileNumber;
    }

CodePudding user response:

Your pattern ^0\\d{10})(^\\d{10})(^63\\d{10}) does not match, as it asserts the start of the string 3 times in a row followed by matching digits.

Instead you can use a match only instead of a capture group, and optionally match either 0 or 63 followed by 10 digits.

Using find() you can first check if there is a match, as find tries to find the next match and returns a boolean.

For a match only, you can use:

^(?:0|63)?\d{10}\b
  • ^ Start of string
  • (?:0|63)? Optionally match 0 or 63
  • \d{10} Match 10 digits
  • \b A word boundary to prevent a partial word match

For example:

Pattern pattern = Pattern.compile("^(?:0|63)?\\d{10}\\b");
String input = "09187654321";
Matcher m = pattern.matcher(input);
if (m.find()) {
    System.out.println(m.group());  
}

See a Java demo and a regex demo.

Using matches, the pattern should match the whole string, which is the case for the given example data.

String input = "09187654321";
if (input.matches("^(?:0|63)?\\d{10}\\b")) {
    System.out.println(input   " matches.");        
}

EDIT

If you must have 3 capture groups, you can use an alternation between the groups and add a word boundary at the end:

^(?:(0\d{10})|(\d{10})|(63\d{10}))\b

The pattern matches:

  • ^ Start of string
  • (?: Non capture group
    • (0\d{10}) Capture group 1, match 0 and 10 digits
    • | Or
    • (\d{10}) Capture group 2, match 10 digits
    • | Or
    • (63\d{10}) Capture group 3, match 63 and 10 digits
  • )\b Close the non capture group a and add a word boundary

Regex demo

For example

private String getInputtedDigitsLocal(final String mobileNumber) {
    final Pattern pattern = Pattern.compile("^(?:(0\\d{10})|(\\d{10})|(63\\d{10}))\\b");
    final Matcher matcher = pattern.matcher(mobileNumber);
    String extractedMobileNumber = "_";

    if (matcher.find()) {
        if (matcher.group(1) != null) {
            extractedMobileNumber = "..";
        }
        if (matcher.group(2) != null) {
            extractedMobileNumber = "..";
        }
        if (matcher.group(3) != null) {
            extractedMobileNumber = "..";
        }
    } else {
        extractedMobileNumber="NOT SUPPORTED FORMAT";
    }
    return extractedMobileNumber;
}

See a Java demo

  • Related