0

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;
    }
iamjoshua
  • 1,157
  • 3
  • 16
  • 33
  • What's the error/wrong output? – user202729 Dec 13 '21 at 11:14
  • 1
    ... you sure the regex matches the input at all? It doesn't look like – user202729 Dec 13 '21 at 11:15
  • 1
    I think you are using `^` incorrectly. It is supposed to match the first character ... and you are using it 3 times. Maybe you mean to put an alternation (`|`) between the groups? At any rate the reason you can't retrieve groups is because the regex doesn't match the input string. (You should test the result of the `find` or `match` call ....) – Stephen C Dec 13 '21 at 11:20
  • Hi all, I updated the question to include why I am trying to have multiple patterns in one regex. Im trying to use Java Matcher and using javas feature to match strings based on groups in a regex. pls see attached link. thx. – iamjoshua Dec 13 '21 at 12:27

1 Answers1

1

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

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • for my sample, I am only trying to match group 1 of the pattern which should throw a match, not the other 2 other group of patterns. I've already made sure the regex for the 2 other patterns work, hence I just really need to determine why may pattern for group 1 doesnt match at all where it should since I am trying to use matcher.group(1) which should use the regex "^0\\d{10}" – iamjoshua Dec 13 '21 at 12:52
  • @iamjoshua That is because your pattern does not match, so there can not be a group value either. If you would add `|` between the separate parts like `(^0\\d{10})|(^\\d{10})|(^63\\d{10})` you can still not get all the right values because the pattern is unanchored and the last part might not match, see https://regex101.com/r/3Uw0Vk/1 If you want the 3 separate groups, you can change the order, and add a word boundary to the end `^(?:(0\\d{10})|(\\d{10})|(63\\d{10}))\\b` See https://regex101.com/r/DYAurH/1 – The fourth bird Dec 13 '21 at 13:05
  • i think is not applicable for my use case where I would have to use || to distiguish between regex patterns I need as I dont need to just match a string, but I also need to determine what string matched a pattern. ie, if it matched pattern with number starting in 63, it then should do this statement, somethig like that, hence I am trying to apply Java groupings since if I knew group 1 pattern is empty, it means it didnt matched that I need. hence I will proceed to group 2 pattern etc using just a single Pattern declaration. – iamjoshua Dec 13 '21 at 13:20
  • Hi, pls see updated question, I added a code snippet for the other implementation of what I am trying to do and why I am trying to use matchers.group(1) syntax to get the value that matched group 1s pattern. – iamjoshua Dec 13 '21 at 13:27
  • @iamjoshua You can use this pattern `^(?:(0\\d{10})|(\\d{10})|(63\\d{10}))\\b` and then check if group 1 is not null, if group 2 is not null etc.. – The fourth bird Dec 13 '21 at 13:28
  • im sorry, im confused as to how I would know what groups to match here, as it says on the linked question above a group of patterns is enclosed in a round brace, hence, if I would have a full Pattern, I need to have group1 pattern (^0\\d{10}$)(^\\d{10}$)(^\\+63\\d{10}$)(^63\\d{10}$) , Java Mach group feature should be able to identify this as (group1)(group2)(group3)(group4) which I could then use to determine if either of this groups are empty or not and thereby use for conditional flow, how I would apply the comment above with Java Matchers group?. can u share a snippet?. thx. – iamjoshua Dec 13 '21 at 13:38
  • 1
    @iamjoshua I have added an example that you can use to implement your logic based on which group is matched. – The fourth bird Dec 13 '21 at 13:50
  • thanks, I was able to make it work with Java SE, though I'm not sure why this same code snippet is not working in Spring Boot with Java 11. But will mark this as an answer, thanks alot. – iamjoshua Dec 13 '21 at 15:34