简体   繁体   English

在Java中使用Regex解析时间

[英]Parsing time with Regex in Java

The code snipped below is trying to extract the hour, minutes and seconds of a string. 下面截断的代码试图提取字符串的小时,分​​钟和秒。 Ex: "PT5M30S" 例如:“ PT5M30S”
"PT1H13M59S" “ PT1H13M59S”

I am getting a NullPointerException in this line (group=null): int number = new Integer(group.substring(0, group.length()-1)); 我在这一行中得到一个NullPointerException(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;
            } 
        }
    }

Just try to compile this code for both the String 's individually, one by one. 只需尝试分别针对两个String编译此代码。

You'll then notice that this program compiles successfully for the second String ie, PT1H13M59S whereas it gives NullPointerException for the first String, ie, PT5M30S 然后,您会注意到该程序已成功为第二个String(即PT1H13M59S编译,而它为第一个String(即PT5M30S提供了NullPointerException

You get this NullPointerException from your first String PT5M30S because this String doesn't contains group 1 . 您从第一个String PT5M30S获得此NullPointerException ,因为此String不包含group 1 Notice that there's no Hour value for your first String PT5M30S 请注意,您的第一个字符串PT5M30S没有Hour


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. 请注意,在第1场比赛的第一个字串中,第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. 只需将您的代码包含在try catch块中获取NullPointerException ,如果发生NullPointerException ,则为所有变量提供默认值。

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;
                    }
                }
            }
        }
    }
}

@rD's solution above is sufficient and well answered ( please choose his ). 上面@rD的解决方案就足够了并且得到了很好的回答(请选择他的)。 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 作为替代方案,在意识到正确答案之前,我也在这里研究解决方案: 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. 我添加了检查null的同一件事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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