Leila
Leila

Reputation: 3

Parsing time with Regex in Java

The code snipped below is trying to extract the hour, minutes and seconds of a string. Ex: "PT5M30S"
"PT1H13M59S"

I am getting a NullPointerException in this line (group=null): int number = new Integer(group.substring(0, group.length()-1));

    // Create a Pattern object
    Pattern pattern = Pattern.compile("PT(\\d+H)?(\\d+M)?(\\d+S)?");
    // Now create matcher object.
    Matcher matcher = pattern.matcher(duracaoStr);

    int hour = 0;
    int minute = 0;
    int second = 0;
    if(matcher.matches()){
        for(int i = 1; i<=matcher.groupCount();i++){
            String group = matcher.group(i);
            int number = new Integer(group.substring(0, group.length()-1));
            if(matcher.group(i).endsWith("H")){
                hour = number;
            } else if(matcher.group(i).endsWith("M")){
                minute = number;
            } else if(matcher.group(i).endsWith("S")){
                second = number;
            } 
        }
    }

Upvotes: 0

Views: 102

Answers (2)

Dave Thomas
Dave Thomas

Reputation: 3827

@rD's solution above is sufficient and well answered ( please choose his ). Just as an alternative I was working on a solution here as well before I realized it was answered properly: https://github.com/davethomas11/stackoverflow_Q_39443620

    // Create a Pattern object
    Pattern pattern = Pattern.compile("PT(\\d+H)?(\\d+M)?(\\d+S)?");
    // Now create matcher object.
    Matcher matcher = pattern.matcher(duracaoStr);

    int hour = 0;
    int minute = 0;
    int second = 0;
    if(matcher.matches()){
        for(int i = 1; i<=matcher.groupCount();i++){
            String group = matcher.group(i);

            //Group will be null if not in pattern
            if (group != null) {
                int number = new Integer(group.substring(0, group.length()-1));
                if(matcher.group(i).endsWith("H")){
                    hour = number;
                } else if(matcher.group(i).endsWith("M")){
                    minute = number;
                } else if(matcher.group(i).endsWith("S")){
                    second = number;
                } 
            }
        }
     }

Same thing I've added checking for null.

Upvotes: 1

Raman Sahasi
Raman Sahasi

Reputation: 31841

Just try to compile this code for both the String's individually, one by one.

You'll then notice that this program compiles successfully for the second String i.e., PT1H13M59S whereas it gives NullPointerException for the first String, i.e., PT5M30S

You get this NullPointerException from your first String PT5M30S because this String doesn't contains group 1. Notice that there's no Hour value for your first String PT5M30S


See this Demo:

RegEx

PT(\d+H)?(\d+M)?(\d+S)?

Input

PT5M30S
PT1H13M59S

Match Information

MATCH 1
2.  [2-4]   `5M`
3.  [4-7]   `30S`
MATCH 2
1.  [10-12] `1H`
2.  [12-15] `13M`
3.  [15-18] `59S`

Notice that in for the first String in Match 1, there's no output for Group 1.


So what you should do is you should perform appropriate validations. Just enclose your code where you're getting NullPointerException in try catch block and if NullPointerException occurs, then give default values to all the variables.

For example:,

import java.util.regex.*;

public class HelloWorld {
    public static void main(String[] args) {
        // Create a Pattern object
        Pattern pattern = Pattern.compile("PT(\\d+H)?(\\d+M)?(\\d+S)?");
        // Now create matcher object.
        Matcher matcher = pattern.matcher("PT5M30S");

        int hour = 0;
        int minute = 0;
        int second = 0;

        if (matcher.matches()) {
            for (int i = 1; i <= matcher.groupCount(); i++) {
                try {
                    String group = matcher.group(i);
                    int number = new Integer(group.substring(0, group.length() - 1));
                    if (matcher.group(i).endsWith("H")) {
                        hour = number;
                    } else if (matcher.group(i).endsWith("M")) {
                        minute = number;
                    } else if (matcher.group(i).endsWith("S")) {
                        second = number;
                    }
                } catch (java.lang.NullPointerException e) {
                    if (i == 1) {
                        hour = 0;
                    } else if (i == 2) {
                        minute = 0;
                    } else if (i == 3) {
                        second = 0;
                    }
                }
            }
        }
    }
}

Upvotes: 1

Related Questions