子组上的 Java 正则表达式

标签 java regex date-parsing

我有以下关于 Java 正则表达式的问题。

当我使用模式定义正则表达式时:

String pattern = "(\\d{4})\\d{2}\\d{2}";

输入字符串为“20180808”, 我可以获得 group(0) - 20180808
但是

group(1) - 不匹配
组(2) - 08
组(3) - 08

我确信正则表达式在其他语言中也有效,例如 Python、C#。

有人可以帮忙吗?感谢您的专家解决方案。

@Test
public void testParseDateStringToMinimumOfTheDate() {
    try {
        UtilsFactory utilsFactory = UtilsFactory.getInstance();
        DateUtils dateUtils = utilsFactory.getInstanceOfDateUtils();
        CalendarUtils calendarUtils = utilsFactory.getInstanceOfCalendarUtils();
        calendarUtils.parseDateStringToMinimumOfTheDate("20180808");
    } catch (Exception e) {
        e.printStackTrace();
    }
} 

    public Calendar parseDateStringToMinimumOfTheDate(String dateString_yyyyMMdd) throws Exception {
    Calendar cal = null;
    String pattern = "(\\d{4})\\d{2}\\d{2}";
    try {
        cal = getMaxUtcCalendarToday();
        List<String> matchStringList = regMatch(dateString_yyyyMMdd, pattern);
        for (int i = 0; i < matchStringList.size(); i++) {

        }
    } catch (Exception e) {
        logger.error(getClassName() + ".parseDateStringToBeginningOfTheDate()- dateString_yyyyMMdd="
                + dateString_yyyyMMdd, e);
        throw e;
    }
    return cal;
}

private List<String> regMatch(String sourceString, String patternString) throws Exception {
    List<String> matchStrList = null;
    Pattern pattern = null;
    Matcher matcher = null;
    try {
        matchStrList = new ArrayList<String>();
        pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
        matcher = pattern.matcher(sourceString);
        while (matcher.find()) {
            matchStrList.add(matcher.group());
        }
    } catch (Exception e) {
        logger.error(
                getClassName() + ".regMatch() - sourceString=" + sourceString + ",patternString=" + patternString,
                e);
        throw e;
    }
    return matchStrList;
}

最佳答案

    Pattern pattern = Pattern.compile("\\d{8}");
    String sourceString = "20180808";
    Matcher matcher = pattern.matcher(sourceString);
    while (matcher.find()) {
        LocalDate date = LocalDate.parse(matcher.group(), DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println(date);
    }

此代码段的输出是预期日期:

2018-08-08

如果您的字符串可能包含比 8 位数日期更多的文本,则使用正则表达式取出这 8 位数是正确的。用于日期的正确类是来自现代 Java 日期和时间 API java.time 的 LocalDate。它是 ISO 日历系统中的日期,没有时间和时区。相比之下,Calendar 表示某些日历系统中带有时区的日期和时间。这比您需要的要多得多。另外,Calendar 类早已过时,并且在四年半前被 java.time 取代,因为它的设计很糟糕。

如果您确实需要某个无法更改或现在不想更改的旧版 API 的 Calendar 对象,请按如下方式进行转换:

        ZoneId zone = ZoneId.of("America/Punta_Arenas");
        ZonedDateTime startOfDay = date.atStartOfDay(zone);
        Calendar cal = GregorianCalendar.from(startOfDay);

如果不是 America/Punta_Arenas,请替换正确的时区。

您的代码出了什么问题?

您的代码没有任何问题,只是它过于复杂并且使用了过时的日期和时间类。

    String patternString = "(\\d{4})(\\d{2})(\\d{2})";
    Pattern pattern = null;
    Matcher matcher = null;
    try {
        pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
        matcher = pattern.matcher(sourceString);
        while (matcher.find()) {
            System.out.println("group(1): " + matcher.group(1));
            System.out.println("group(2): " + matcher.group(2));
            System.out.println("group(3): " + matcher.group(3));
        }
    } catch (Exception e) {
        // TODO handle exception
        throw e;
    }

此代码段的输出是:

group(1): 2018
group(2): 08
group(3): 08

链接

Oracle tutorial: Date Time解释如何使用java.time

关于子组上的 Java 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52136250/

相关文章:

java - 使用 XML 配置在 Spring 中为 Jackson 启用 DEFAULT_VIEW_INCLUSION 功能

javascript - 正则表达式不工作

java - java中常见的字符串长度

javascript - 使用 RegExp 在 JavaScript 中拆分字符串,忽略方括号内的定界符

java - 无法使用 DateTimeFormatter 解析月+日

java - <foreach> 下的 <param> 不支持嵌套文件集元素

java - 无法找到数据库位置

java - Java中检测日期格式

c++ - 如何正确地将字符串转换为 std::chrono::system_clock::time_point?

java - 使用手动依赖注入(inject)构建多级对象树