Create regex for Cron expression

I need to write a regular expression that will look for all these features in a string

  • 28 2 7 1 1
  • 28 2 7 1 *
  • 28 2 7 * *
  • 28 2 * * *
  • 28 * * * *
  • * * * * *

I thought something like this: [28 *] [2 *] [7 *] [1 *] [1 *], but this does not work. Any ideas?

+4
source share
8 answers

It's hard to make an exact regex without knowing which program you will use to run it, but this should work:

(28|\*) (2|\*) (7|\*) (1|\*) (1|\*) 
+9
source

I just finished writing, so here is mine, hope this helps.

This should allow * or * / num, and also limit the numerical values ​​to their logical range (1-12 for months, 0-24 for hours, etc.)

 /^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$/ 
+11
source

It took me some time: D it is checked based on this documentation: http://en.wikipedia.org/wiki/Cron. However, it does not take into account that you cannot specify the day of the week and day of the month, i.e. you can specify both according to this regex. This can be used for boost :: regex

  (((([*])|(((([0-5])?[0-9])((-(([0-5])?[0-9])))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?))(,(((([*])|(((([0-5])?[0-9])((-(([0-5])?[0-9])))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?)))* (((([*])|(((((([0-1])?[0-9]))|(([2][0-3])))((-(((([0-1])?[0-9]))|(([2][0-3])))))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?))(,(((([*])|(((((([0-1])?[0-9]))|(([2][0-3])))((-(((([0-1])?[0-9]))|(([2][0-3])))))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?)))* (((((((([*])|(((((([1-2])?[0-9]))|(([3][0-1]))|(([1-9])))((-(((([1-2])?[0-9]))|(([3][0-1]))|(([1-9])))))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?))|(L)|(((((([1-2])?[0-9]))|(([3][0-1]))|(([1-9])))W))))(,(((((([*])|(((((([1-2])?[0-9]))|(([3][0-1]))|(([1-9])))((-(((([1-2])?[0-9]))|(([3][0-1]))|(([1-9])))))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?))|(L)|(((((([1-2])?[0-9]))|(([3][0-1]))|(([1-9])))W)))))*)|([?])) (((([*])|((((([1-9]))|(([1][0-2])))((-((([1-9]))|(([1][0-2])))))?))|((((JAN)|(FEB)|(MAR)|(APR)|(MAY)|(JUN)|(JUL)|(AUG)|(SEP)|(OKT)|(NOV)|(DEC))((-((JAN)|(FEB)|(MAR)|(APR)|(MAY)|(JUN)|(JUL)|(AUG)|(SEP)|(OKT)|(NOV)|(DEC))))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?))(,(((([*])|((((([1-9]))|(([1][0-2])))((-((([1-9]))|(([1][0-2])))))?))|((((JAN)|(FEB)|(MAR)|(APR)|(MAY)|(JUN)|(JUL)|(AUG)|(SEP)|(OKT)|(NOV)|(DEC))((-((JAN)|(FEB)|(MAR)|(APR)|(MAY)|(JUN)|(JUL)|(AUG)|(SEP)|(OKT)|(NOV)|(DEC))))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?)))* (((((((([*])|((([0-6])((-([0-6])))?))|((((SUN)|(MON)|(TUE)|(WED)|(THU)|(FRI)|(SAT))((-((SUN)|(MON)|(TUE)|(WED)|(THU)|(FRI)|(SAT))))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?))|((([0-6])L))|(W)|(([#][1-5]))))(,(((((([*])|((([0-6])((-([0-6])))?))|((((SUN)|(MON)|(TUE)|(WED)|(THU)|(FRI)|(SAT))((-((SUN)|(MON)|(TUE)|(WED)|(THU)|(FRI)|(SAT))))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?))|((([0-6])L))|(W)|(([#][1-5])))))*)|([?]))((( (((([*])|((([1-2][0-9][0-9][0-9])((-([1-2][0-9][0-9][0-9])))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?))(,(((([*])|((([1-2][0-9][0-9][0-9])((-([1-2][0-9][0-9][0-9])))?)))((/(([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?([0-9])?[0-9])))?)))*))?) 
+5
source

For checking cron expressions in general, this will be highly dependent on the particular implementation you are using

rules

General format

Typically, most adhere to the following format:

 | Field name | Mandatory? | Allowed values | Special characters | | ------------- | ---------- | --------------- | ------------------ | | Seconds | No* | 0-59 | * / , - | | Minutes | Yes | 0-59 | * / , - | | Hours | Yes | 0-23 | * / , - | | Day of month | Yes | 1-31 | * / , - LW | | Month | Yes | 1-12 or JAN-DEC | * / , - | | Day of week | Yes | 0-6 or SUN-SAT | * / , - L # | | Year | No* | 1970–2099 | * / , - | 

* where seconds and years are non-standard and sometimes not included

Predefined scheduling macros :

Some flavors allow for predefined time periods, for example:

 | Entry | Equivalent to | | ---------- | ------------- | | @annually | 0 0 0 1 1 * * | | @yearly | 0 0 0 1 1 * * | | @monthly | 0 0 0 1 * * * | | @weekly | 0 0 0 * * 0 * | | @daily | 0 0 0 * * * * | | @hourly | 0 0 * * * * * | | @reboot | | 
Intervals

Intervals

Some variations allow you to use the @every <duration> syntax with the following time units:

 | Unit | Definition | | ------ | ----------- | | ns | nanosecond | | us, Β΅s | microsecond | | ms | millisecond | | s | second | | m | minute | | h | hour | 

Users

Regex Predefined Macros

To test predefined macros, you can use the following regular expression :

 /@(annually|yearly|monthly|weekly|daily|hourly|reboot)/ 

Which will pass the following test cases:

 @daily @hourly 

@every regex

To check the duration of @every , you can use the following regular expression :

 /@every (\d+(ns|us|Β΅s|ms|s|m|h))+/ 

Which will pass the following test cases:

 @every 5s @every 20h30m 

Individual Cron Terms

Checking cron terms in a regex is a bit more complicated since there are so many options.

Just by focusing on one term , all of the following are valid:

  • Two or more numbers separated ,
  • Two numbers separated by / or -
  • 1-2 digit number
  • One *

To test a single term, we can use the following regular expression :

 /(\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*/ 

where [TG415] just guarantees you have 1 or more numeric digits

Which will pass the following test cases:

 1,2,3 1,2 1/2 1-2 1 * 

Combining Cron Terms

To test the full expression, we can just make sure that we have {5,7} terms with the following regular expression :

 /(((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7}/ 

If we wanted to distinguish between each term, we need to check the numbers in a certain range :

 | Allowed values | Regex | | -------------- | ------------------------- | | 0-59 | [1-5]?[0-9] | | 0-23 | 2[0-3]|1[0-9]|[0-9] | | 1-31 | 3[01]|[12][0-9]|[1-9] | | 1-12 | 1[0-2]|[1-9] | | 0-6 | [0-6] | | 1970–2099 | 19[7-9][0-9]|20[0-9][0-9] | 

If, however, we just want to make sure that something looks like an expression of a regular expression, without worrying about which term is days compared to hours, the expression remains much cleaner, so for simplicity I'll go

Putting it all together

Combining the above statements, we can get a relatively simple check that the term looks like a regular expression with an expression as follows :

 /(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|Β΅s|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})/ 

Additional Resources

+1
source

Your current regular expression will only match 5 characters, since each character class can only match one character. For each position, you either want to match a number or * , with one or more spaces between each position, you can do this with the following:

 (28|\*) +[2*] +[7*] +[1*] +[1*] 

Note that since the first number has two digits, you need to use alternation instead of a character class.

You might also want to add some bindings to your regular expression so that it does not match only part of the string, if necessary, add ^ to the beginning and $ to the end.

0
source

do the simplest thing that could work

 "^28 2 7 1 1$|^28 2 7 1 \*$|^28 2 7 \* \*$|^28 2 \* \* \*$|^28 \* \* \* \*$|^\* \* \* \* \*$" 

http://rubular.com/r/Z0hfT5X9K8

0
source

Not sure if this might help someone, but here is some regex to check the values ​​of temporary parameters without a function to write names on weekdays.

 //string validation function allowed_characters($value, $mode){ switch ($mode) { case '0': //0-59 $preg_code = "^(((([0-5]?[0-9]|60)(-([0-5]?[0-9]|60)){0,1}?)|\*)(,([0-5]?[0-9]|60)((-([0-5]?[0-9]|60)){0,1}?))*?)$"; break; case '1': //0-23 $preg_code = "^(((([0-1]?[0-9]|2[0-4])(-([0-1]?[0-9]|2[0-4])){0,1}?)|\*)(,([0-1]?[0-9]|2[0-4])((-([0-1]?[0-9]|2[0-4])){0,1}?))*?)$"; break; case '2': //1-31 $preg_code = "^(((([0-2]?[0-9]|3[0-1])(-([0-2]?[0-9]|3[0-1])){0,1}?)|\*)(,([0-2]?[0-9]|3[0-1])((-([0-2]?[0-9]|3[0-1])){0,1}?))*?)$"; break; case '3': //0-12 $preg_code = "^(((([0]?[0-9]|1[0-2])(-([0]?[0-9]|1[0-2])){0,1}?)|\*)(,([0]?[0-9]|1[0-2])((-([0]?[0-9]|1[0-2])){0,1}?))*?)$"; break; case '4': //0-6 $preg_code = "^(((([0]?[[0-7])(-([0]?[0-7])){0,1}?)|\*)(,([0]?[0-7])((-([0]?[0-7])){0,1}?))*?)$"; break; default: return false; break; } 
0
source

To avoid a very long line, you can break the cron line and then map each field to the pictures below. Value range, step and comma groups are supported!

 // minute: 0-59 /^(\*|[1-5]?[0-9](-[1-5]?[0-9])?)(\/[1-9][0-9]*)?(,(\*|[1-5]?[0-9](-[1-5]?[0-9])?)(\/[1-9][0-9]*)?)*$/ // hour: 0-23 /^(\*|(1?[0-9]|2[0-3])(-(1?[0-9]|2[0-3]))?)(\/[1-9][0-9]*)?(,(\*|(1?[0-9]|2[0-3])(-(1?[0-9]|2[0-3]))?)(\/[1-9][0-9]*)?)*$/ // monthDay: 1-31 /^(\*|([1-9]|[1-2][0-9]?|3[0-1])(-([1-9]|[1-2][0-9]?|3[0-1]))?)(\/[1-9][0-9]*)?(,(\*|([1-9]|[1-2][0-9]?|3[0-1])(-([1-9]|[1-2][0-9]?|3[0-1]))?)(\/[1-9][0-9]*)?)*$/ // month: 1-12 /^(\*|([1-9]|1[0-2]?)(-([1-9]|1[0-2]?))?)(\/[1-9][0-9]*)?(,(\*|([1-9]|1[0-2]?)(-([1-9]|1[0-2]?))?)(\/[1-9][0-9]*)?)*$/ // weekDay: 0-6 /^(\*|[0-6](-[0-6])?)(\/[1-9][0-9]*)?(,(\*|[0-6](-[0-6])?)(\/[1-9][0-9]*)?)*$/ 

Unable to check range bounds i.e. here 0,*/3,6-1/20 acceptable

A very useful site that can help: https://crontab.guru/

0
source

All Articles