子群上的Java正则表达式

子群上的Java正则表达式,java,regex,date-parsing,Java,Regex,Date Parsing,我有以下关于Java正则表达式的问题 当我使用模式定义正则表达式时: String pattern = "(\\d{4})\\d{2}\\d{2}"; 输入字符串为“20180808”, 我可以得到组(0)-20180808 但是 组(1)-不匹配 组(2)-08 组(3)-08 我确信正则表达式可以在其他语言中有效,比如Python、C# 有人能帮忙吗?感谢您的专家解决方案 @Test public void testParseDateStringToMinimumOfTheDate() {

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

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

String pattern = "(\\d{4})\\d{2}\\d{2}";
输入字符串为
“20180808”
, 我可以得到
组(0)
-
20180808

但是

组(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;
}
@测试
public void testParseDateStringToMinimumOfDate(){
试一试{
UtilsFactory UtilsFactory=UtilsFactory.getInstance();
DateUtils DateUtils=utilsFactory.getInstanceOfDateUtils();
CalendarUtils CalendarUtils=utilsFactory.GetInstanceOffCalendarUtils();
calendarUtils.ParseDateStringToMinimumofDate(“20180808”);
}捕获(例外e){
e、 printStackTrace();
}
} 
公共日历ParseDateStringToMinimumOfDate(字符串dateString_yyyyymmdd)引发异常{
日历cal=空;
String pattern=“(\\d{4})\\d{2}\\d{2}”;
试一试{
cal=getMaxUtcCalendarToday();
List matchStringList=regMatch(日期字符串_yyyyMMdd,模式);
对于(int i=0;i
您的正则表达式没有任何问题(正如您提到的
(\d{4})(\d{2})(\d{2})
。您所做的错误是,您没有正确地抓取捕获的组。请将您的方法重构为此

private static List<String> regMatch(String sourceString, String patternString) {
      List<String> matchStrList = new ArrayList<>();

      Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
      Matcher matcher = pattern.matcher(sourceString);

      if(matcher.find()) {
          for(int i = 1; i <= matcher.groupCount(); i++) {
            matchStrList.add(matcher.group(i));
          }
      }

   return matchStrList;
}
并且
groupCount()
方法返回匹配器模式中存在的捕获组数

旁注 正如@haba713在评论中提到的,您可能不想为了解析一个日期而进行所有这些正则表达式的麻烦。您可以简单地使用
SimpleDateFormat

SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd");
System.out.println(formater.parse(dateString));
此代码段的输出为预期日期:

2018-08-08

如果字符串可能包含的文本多于8位日期,则使用正则表达式删除这8位数字是正确的。用于日期的正确类是java.time(现代java日期和时间API)中的
LocalDate
。它是ISO日历系统中的一个日期,没有时间和时区相比之下,在某些日历系统中,alendar表示带时区的日期和时间。它远远超出了您的需要。此外,
calendar
类早已过时,四年半前被java.time所取代,因为它的设计很差

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

        ZoneId zone = ZoneId.of("America/Punta_Arenas");
        ZonedDateTime startOfDay = date.atStartOfDay(zone);
        Calendar cal = GregorianCalendar.from(startOfDay);
如果不是美洲/蓬塔竞技场,请替换正确的时区

你的代码出了什么问题? 您的代码没有什么问题,只是过于复杂,并且使用了过时的日期和时间类

    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;
    }
此代码段的输出为:

链接
解释如何使用
java.time

Hei@manpakhong,你也可以编辑你的问题以进行澄清。正则表达式很好,我对它进行了测试。这有点离题,但我将用于解析日期字符串。
string dateStr=“20180808”;DateFormat DateFormat=new SimpleDateFormat(“yyymmdd”);Calendar cal=Calendar.getInstance();cal.setTime(dateFormat.parse(dateStr))
你的帖子里似乎没有问任何问题。你有什么问题?@haba713请不要教年轻人使用早已过时且臭名昭著的
SimpleDateFormat
类。至少不是第一选择。而且不是没有任何保留。今天我们有了更好的in及其e> DateTimeFormatter@Ole V.V.,@manpakhong似乎想检索日期字符串的日历。如果获取年、月和月日就足够了,请尝试以下操作:
string dateStr=“20180808”;DateTimeFormatter formatter=DateTimeFormatter.of模式(“yyyyMMdd”);LocalDate date=LocalDate.parse(dateStr,formatter);int year=date.getYear();int month=date.getMonthValue();int day=date.getDayOfMonth()
哦,不。你不应该想让正则表达式麻烦,应该更喜欢一个库类来解析日期字符串。但是,你也应该避免使用过时且臭名昭著的
SimpleDataFormat
类。不管你使用的是这个类还是现代的替代品
DateTimeFormat
类,格式模式字符串区分大小写,
YYYYMMDD
有几个字母的大小写错误,在大多数情况下会给出异常或不正确的结果。谢谢,也就是说!我被调试器搞糊涂了,你的补充说明很好!@OleV.V。问题是关于从文本中捕获regex子组。解决这个问题使用Java日期分析器是不同的问题和方法。它总是更好,可以在许多方面进行尝试。但我指出了他在代码中到底做错了什么。很抱歉,我不清楚,@ShafinMahmud.Y
        ZoneId zone = ZoneId.of("America/Punta_Arenas");
        ZonedDateTime startOfDay = date.atStartOfDay(zone);
        Calendar cal = GregorianCalendar.from(startOfDay);
    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