Verifying a cron expression is valid in Java

前端 未结 6 1343
梦谈多话
梦谈多话 2020-12-15 03:08

I\'m writing a scheduling application in Java using Quartz. I\'m using the CronTrigger, but my cron expressions are entered into a database before they are scheduled and are

6条回答
  •  无人及你
    2020-12-15 03:49

    I've modified the following code added by @ph4r05 to generate a regex as well; here's the regex:

    ^\s*($|#|\w+\s*=|(\?|\*|(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?(?:,(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?)*)\s+(\?|\*|(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?(?:,(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?)*)\s+(\?|\*|(?:[01]?\d|2[0-3])(?:(?:-|\/|\,)(?:[01]?\d|2[0-3]))?(?:,(?:[01]?\d|2[0-3])(?:(?:-|\/|\,)(?:[01]?\d|2[0-3]))?)*)\s+(\?|\*|(?:0?[1-9]|[12]\d|3[01])(?:(?:-|\/|\,)(?:0?[1-9]|[12]\d|3[01]))?(?:,(?:0?[1-9]|[12]\d|3[01])(?:(?:-|\/|\,)(?:0?[1-9]|[12]\d|3[01]))?)*)\s+(\?|\*|(?:[1-9]|1[012])(?:(?:-|\/|\,)(?:[1-9]|1[012]))?(?:L|W)?(?:,(?:[1-9]|1[012])(?:(?:-|\/|\,)(?:[1-9]|1[012]))?(?:L|W)?)*|\?|\*|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?(?:,(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)*)\s+(\?|\*|(?:[0-6])(?:(?:-|\/|\,|#)(?:[0-6]))?(?:L)?(?:,(?:[0-6])(?:(?:-|\/|\,|#)(?:[0-6]))?(?:L)?)*|\?|\*|(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?(?:,(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?)*)(|\s)+(\?|\*|(?:|\d{4})(?:(?:-|\/|\,)(?:|\d{4}))?(?:,(?:|\d{4})(?:(?:-|\/|\,)(?:|\d{4}))?)*))$
    

    Here's the java code:

    private static String cronRegex = null;
    
    public static String getCronRegex()
    {
      if (cronRegex == null)
      {
        // numbers intervals and regex
        Map numbers = new HashMap();
        numbers.put("sec", "[0-5]?\\d");
        numbers.put("min", "[0-5]?\\d");
        numbers.put("hour", "[01]?\\d|2[0-3]");
        numbers.put("day", "0?[1-9]|[12]\\d|3[01]");
        numbers.put("month", "[1-9]|1[012]");
        numbers.put("dow", "[0-6]");
        numbers.put("year", "|\\d{4}");
    
        Map field_re = new HashMap();
    
        // expand regex to contain different time specifiers
        for (String field : numbers.keySet())
        {
          String number = numbers.get(field);
          String range = "(?:" + number + ")(?:(?:-|\\/|\\," +  ("dow".equals(field)? "|#" :    "") + 
    
            ")(?:" + number + "))?" +  ("dow".equals(field)? "(?:L)?" : ("month".equals(field)? "(?:L|W)?" : ""));
          field_re.put(field, "\\?|\\*|" + range + "(?:," + range + ")*");
        }
    
        // add string specifiers
        String monthRE = field_re.get("month");
        String monthREVal =   "JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC";
        String monthRERange = "(?:" + monthREVal + ")(?:(?:-)(?:" + monthREVal + "))?" ; 
        monthRE = monthRE +  "|\\?|\\*|" + monthRERange + "(?:," + monthRERange + ")*" ;
        field_re.put("month", monthRE);
    
        String dowRE = field_re.get("dow");
        String dowREVal = "MON|TUE|WED|THU|FRI|SAT|SUN";
        String dowRERange = "(?:" + dowREVal + ")(?:(?:-)(?:" + dowREVal + "))?" ;
    
        dowRE = dowRE + "|\\?|\\*|" + dowRERange + "(?:," + dowRERange + ")*" ;
        field_re.put("dow", dowRE);
    
        StringBuilder fieldsReSB = new StringBuilder();
        fieldsReSB.append("^\\s*(").append("$") //
          .append("|#") //
          .append("|\\w+\\s*=") //
          .append("|") //
          .append("(")//
          .append(field_re.get("sec")).append(")\\s+(")//
          .append(field_re.get("min")).append(")\\s+(")//
          .append(field_re.get("hour")).append(")\\s+(")//
          .append(field_re.get("day")).append(")\\s+(")//
          .append(field_re.get("month")).append(")\\s+(")//
          .append(field_re.get("dow")).append(")(|\\s)+(")//
          .append(field_re.get("year"))//
          .append(")")//
          .append(")")//
          .append("$");
    
        cronRegex = fieldsReSB.toString();
      }
      return cronRegex;
    }
    

    I'm by no means a regex expert, but at least this seems to work on all the examples given by the quartz documentation

提交回复
热议问题