Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex not capturing matching in expected groups

I have been working on requirement and I need to create a regex on following string:

startDate:[2016-10-12T12:23:23Z:2016-10-12T12:23:23Z]

There can be many variations of this string as follows:

startDate:[*;2016-10-12T12:23:23Z]
startDate:[2016-10-12T12:23:23Z;*]
startDate:[*;*]

startDate in above expression is a key name which can be anything like endDate, updateDate etc. which means we cant hardcode that in a expression. The key name can be accepted as any word though [a-zA-Z_0-9]*

I am using the following compiled pattern

Pattern.compile("([[a-zA-Z_0-9]*):(\\[[[\\*]|[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[Z]];[[\\*]|[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[Z]]\\]])");

The pattern matches but the groups created are not what I expect. I want the group surrounded by parenthesis below:

(startDate):([*:2016-10-12T12:23:23Z])

group1 = "startDate"
group2 = "[*;2016-10-12T12:23:23Z]"

Could you please help me with correct expression in Java and groups?

like image 862
Vishal Avatar asked Oct 07 '16 05:10

Vishal


1 Answers

You are using [ rather than ( to wrap options (i.e. using |).

For example, the following code works for me:

Pattern pattern = Pattern.compile("(\\w+):(\\[(\\*|\\d{4}):\\*\\])");
Matcher matcher = pattern.matcher(text);
if (matcher.matches()) {
    for (int i = 0; i < matcher.groupCount() + 1; i++) {
        System.out.println(i + ":" + matcher.group(i));
    }
} else {
    System.out.println("no match");
}

To simplify things I just use the year but I'm sure it'll work with the full timestamp string.

This expression captures more than you need in groups but you can make them 'non-capturing' using the (?: ) construct.

Notice in this that I simplified some of your regexp using the predefined character classes. See http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html for more details.

like image 134
sprinter Avatar answered Oct 20 '22 00:10

sprinter