无法让正则表达式工作

时间:2013-11-04 22:21:15

标签: java regex jsoup

我想弄清楚如何编写一个与时间匹配的regex。时间可能如下所示:11:15-12:1511-12:1511-12等等。我现在拥有的是:

\\d{2}:?\\d{0,2}-{1}\\d{2}:?\\d{0,2}

直到日期出现才有效。如果此类字符串regex,则2013-11-05将捕获此Lookbehind。我不希望它找到日期。我知道我应该使用Jsoup,但我无法让它发挥作用。

我正在使用Element getElementsMatchingOwnText <td class="text">2013-11-04</td> 方法,如果该信息有任何意义。

时间字符串包含在html源代码中。像这样:(但上面和下面有更多的文字)

{{1}}

2 个答案:

答案 0 :(得分:3)

试试这个。从基础正则表达式开始:

\d{1,2}(:\d\d)?-\d{1,2}(:\d\d)?

那是:

  • 一到两位数字,可选地后跟:还有两位数字
  • 后跟连字符
  • 后跟一到两位数字,可选地后跟:还有两位数字

这符合您的所有核心案例:

11-12
1-2
1:15-2
10-3:45
2:15-11:30

等。现在混合使用负向后观和负前瞻,以使出现在不需要的上下文中的匹配无效。当数字或破折号或冒号直接出现在匹配的左侧或右侧时,让匹配无效:

负面的背后:(?<!\d|-|:) 否定前瞻:(?!\d|-|:)

在开始时扯掉负面观察,然后在结尾处看到负面看,你得到:

(?<!\d|-|:)(\d{1,2}(:\d\d)?-\d{1,2}(:\d\d)?)(?!\d|-|:)

或作为Java字符串(按请求)

Pattern p = Pattern.compile("(?<!\\d|-|:)(\\d{1,2}(:\\d\\d)?-\\d{1,2}(:\\d\\d)?)(?!\\d|-|:)");

现在虽然看起来已经消除了日期内的匹配,但你仍然会匹配一些愚蠢的东西,比如99:99-88:88,因为\ d匹配任何数字0-9。您可以将更多限制性字符类混合到此正则表达式中以解决该问题。例如,使用12小时制:

对于小时部分,请使用

(1[0-2]|0?[1-9])

而不是

\d{1,2}

对于分钟部分使用

(0[0-9]|[1-5][0-9])

而不是

\d\d

将限制性更强的字符类混合到正则表达式中会产生几乎无法理解和维护的野兽:

(?<!\d|-|:)(((1[0-2]|0?[1-9]))(:((0[0-9]|[1-5][0-9])))?-(1[0-2]|0?[1-9])(:((0[0-9]|[1-5][0-9])))?)(?!\d|-|:)

作为Java代码:

Pattern p = Pattern.compile("(?<!\\d|-|:)(((1[0-2]|0?[1-9]))(:((0[0-9]|[1-5][0-9])))?-(1[0-2]|0?[1-9])(:((0[0-9]|[1-5][0-9])))?)(?!\\d|-|:)");

答案 1 :(得分:1)

简单方法:

((\d{2}(:\d{2})?)-?){2}

更安全;更详细的正则表达式:

([0-1]?[0-9]|[2][0-3])(:([0-5][0-9]))?-([0-1]?[0-9]|[2][0-3])(:([0-5][0-9]))?

行动中的例子:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class App {
    private static final String TIME_FORMAT = "%02d:%02d";
    private static final String TIME_RANGE = "([0-1]?[0-9]|[2][0-3])(:([0-5][0-9]))?-([0-1]?[0-9]|[2][0-3])(:([0-5][0-9]))?";

    public static void main(String[] args) {
        String passage = "The time can look like this: 11:15-12:15 or 11-12:15 or 11-12 and so on.";
        Pattern pattern = Pattern.compile(TIME_RANGE);
        Matcher matcher = pattern.matcher(passage);
        int count = 0;

        while (matcher.find()) {
            String time1 = formattedTime(matcher.group(1), matcher.group(3));
            String time2 = formattedTime(matcher.group(4), matcher.group(6));
            System.out.printf("Time #%d: %s - %s\n", count, time1, time2);
            count++;
        }
    }

    private static String formattedTime(String strHour, String strMinute) {
        int intHour = parseInt(strHour);
        int intMinute = parseInt(strMinute);

        return String.format(TIME_FORMAT, intHour, intMinute);
    }

    private static int parseInt(String str) {
        return str != null ? Integer.parseInt(str) : 0;
    }
}

输出:

Time #0: 11:15 - 12:15
Time #1: 11:00 - 12:15
Time #2: 11:00 - 12:00