简体   繁体   中英

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?

You are using [ rather than ( to wrap options (ie 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.

Here is a solution which uses your original regex, modified so that it actually returns the groups you want:

String content = "startDate:[2016-10-12T12:23:23Z:2016-10-12T12:23:23Z]";
Pattern pattern = Pattern.compile("([a-zA-Z_0-9]*):(\\[(?:\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z|\\*):(?:\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z|\\*)\\])");
Matcher matcher = pattern.matcher(content);
// remember to call find() at least once before trying to access groups
matcher.find();

System.out.println("group1 = " + matcher.group(1));
System.out.println("group2 = " + matcher.group(2));

Output:

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

This code has been tested on IntelliJ and appears to be working correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM