Javascript判断Crontab表达式是否合法
这段时间在做Quartz任务调度,使用的Crontab表达式实现的。Crontab由前端页面输入,作为参数穿入后台。
虽然Quartz具有校验Crontab表达式的方法,如下:
boolean cronExpressionFlag = CronExpression.isValidExpression(crontab);
但是我一直想在前端直接验证,即不需要通过异步的方式向后台获取验证结果,找了好久,发现没有现成的框架可以使用,于是自己根据网上搜索到的资料,写了这个js脚本。
这个脚本目前对日和星期的判断还有点小问题,不过不影响使用。
以后如果有时间,继续完善这个脚本,废话不多说了,上代码:
function cronValidate() {
var cron = $("#cron").val();
var result = CronExpressionValidator.validateCronExpression(cron);
if(result == true){
alert("格式正确");
}
else{
alert("格式错误");
}
return CronExpressionValidator.validateCronExpression(cron);
}
function CronExpressionValidator() {
}
CronExpressionValidator.validateCronExpression = function(value) {
var results = true;
if (value == null || value.length == 0) {
return false;
}
// split and test length
var expressionArray = value.split(" ");
var len = expressionArray.length;
if ((len != 6) && (len != 7)) {
return false;
}
// check only one question mark
var match = value.match(/\?/g);
if (match != null && match.length > 1) {
return false;
}
// check only one question mark
var dayOfTheMonthWildcard = "";
// if appropriate length test parts
// [0] Seconds 0-59 , - * /
if (CronExpressionValidator.isNotWildCard(expressionArray[0], /[\*]/gi)) {
if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[0], [0, 59], "seconds")) {
return false;
}
}
// [1] Minutes 0-59 , - * /
if (CronExpressionValidator.isNotWildCard(expressionArray[1], /[\*]/gi)) {
if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[1], [0, 59], "minutes")) {
return false;
}
}
// [2] Hours 0-23 , - * /
if (CronExpressionValidator.isNotWildCard(expressionArray[2], /[\*]/gi)) {
if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[2], [0, 23], "hours")) {
return false;
}
}
// [3] Day of month 1-31 , - * ? / L W C
if (CronExpressionValidator.isNotWildCard(expressionArray[3], /[\*\?]/gi)) {
if (!CronExpressionValidator.segmentValidator("([0-9LWC\\\\,-\\/])", expressionArray[3], [1, 31], "days of the month")) {
return false;
}
} else {
dayOfTheMonthWildcard = expressionArray[3];
}
// [4] Month 1-12 or JAN-DEC , - * /
if (CronExpressionValidator.isNotWildCard(expressionArray[4], /[\*]/gi)) {
expressionArray[4] = CronExpressionValidator.convertMonthsToInteger(expressionArray[4]);
if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[4], [1, 12], "months")) {
return false;
}
}
// [5] Day of week 1-7 or SUN-SAT , - * ? / L C #
if (CronExpressionValidator.isNotWildCard(expressionArray[5], /[\*\?]/gi)) {
expressionArray[5] = CronExpressionValidator.convertDaysToInteger(expressionArray[5]);
if (!CronExpressionValidator.segmentValidator("([0-9LC#\\\\,-\\/])", expressionArray[5], [1, 7], "days of the week")) {
return false;
}
} else {
if (dayOfTheMonthWildcard == String(expressionArray[5])) {
return false;
}
}
// [6] Year empty or 1970-2099 , - * /
if (len == 7) {
if (CronExpressionValidator.isNotWildCard(expressionArray[6], /[\*]/gi)) {
if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[6], [1970, 2099], "years")) {
return false;
}
}
}
return true;
}
// ----------------------------------
// isNotWildcard 静态方法;
// ----------------------------------
CronExpressionValidator.isNotWildCard = function(value, expression) {
var match = value.match(expression);
return (match == null || match.length == 0) ? true : false;
}
// ----------------------------------
// convertDaysToInteger 静态方法;
// ----------------------------------
CronExpressionValidator.convertDaysToInteger = function(value) {
var v = value;
v = v.replace(/SUN/gi, "1");
v = v.replace(/MON/gi, "2");
v = v.replace(/TUE/gi, "3");
v = v.replace(/WED/gi, "4");
v = v.replace(/THU/gi, "5");
v = v.replace(/FRI/gi, "6");
v = v.replace(/SAT/gi, "7");
return v;
}
// ----------------------------------
// convertMonthsToInteger 静态方法;
// ----------------------------------
CronExpressionValidator.convertMonthsToInteger = function(value) {
var v = value;
v = v.replace(/JAN/gi, "1");
v = v.replace(/FEB/gi, "2");
v = v.replace(/MAR/gi, "3");
v = v.replace(/APR/gi, "4");
v = v.replace(/MAY/gi, "5");
v = v.replace(/JUN/gi, "6");
v = v.replace(/JUL/gi, "7");
v = v.replace(/AUG/gi, "8");
v = v.replace(/SEP/gi, "9");
v = v.replace(/OCT/gi, "10");
v = v.replace(/NOV/gi, "11");
v = v.replace(/DEC/gi, "12");
return v;
}
// ----------------------------------
// segmentValidator 静态方法;
// ----------------------------------
CronExpressionValidator.segmentValidator = function(expression, value, range, segmentName) {
var v = value;
var numbers = new Array();
// first, check for any improper segments
var reg = new RegExp(expression, "gi");
if (!reg.test(v)) {
return false;
}
// check duplicate types
// check only one L
var dupMatch = value.match(/L/gi);
if (dupMatch != null && dupMatch.length > 1) {
return false;
}
// look through the segments
// break up segments on ','
// check for special cases L,W,C,/,#,-
var split = v.split(",");
var i = -1;
var l = split.length;
var match;
while (++i < l) {
// set vars
var checkSegment = split[i];
var n;
var pattern = /(\w*)/;
match = pattern.exec(checkSegment);
// if just number
pattern = /(\w*)\-?\d+(\w*)/;
match = pattern.exec(checkSegment);
if (match
&& match[0] == checkSegment
&& checkSegment.indexOf("L") == -1
&& checkSegment.indexOf("l") == -1
&& checkSegment.indexOf("C") == -1
&& checkSegment.indexOf("c") == -1
&& checkSegment.indexOf("W") == -1
&& checkSegment.indexOf("w") == -1
&& checkSegment.indexOf("/") == -1
&& (checkSegment.indexOf("-") == -1 || checkSegment
.indexOf("-") == 0) && checkSegment.indexOf("#") == -1) {
n = match[0];
if (n && !(isNaN(n)))
numbers.push(n);
else if (match[0] == "0")
numbers.push(n);
continue;
}
// includes L, C, or w
pattern = /(\w*)L|C|W(\w*)/i;
match = pattern.exec(checkSegment);
if (match
&& match[0] != ""
&& (checkSegment.indexOf("L") > -1
|| checkSegment.indexOf("l") > -1
|| checkSegment.indexOf("C") > -1
|| checkSegment.indexOf("c") > -1
|| checkSegment.indexOf("W") > -1 || checkSegment
.indexOf("w") > -1)) {
// check just l or L
if (checkSegment == "L" || checkSegment == "l")
continue;
pattern = /(\w*)\d+(l|c|w)?(\w*)/i;
match = pattern.exec(checkSegment);
// if something before or after
if (!match || match[0] != checkSegment) {
continue;
}
// get the number
var numCheck = match[0];
numCheck = numCheck.replace(/(l|c|w)/ig, "");
n = Number(numCheck);
if (n && !(isNaN(n)))
numbers.push(n);
else if (match[0] == "0")
numbers.push(n);
continue;
}
var numberSplit;
// includes /
if (checkSegment.indexOf("/") > -1) {
// take first #
numberSplit = checkSegment.split("/");
if (numberSplit.length != 2) {
continue;
} else {
n = numberSplit[0];
if (n && !(isNaN(n)))
numbers.push(n);
else if (numberSplit[0] == "0")
numbers.push(n);
continue;
}
}
// includes #
if (checkSegment.indexOf("#") > -1) {
// take first #
numberSplit = checkSegment.split("#");
if (numberSplit.length != 2) {
continue;
} else {
n = numberSplit[0];
if (n && !(isNaN(n)))
numbers.push(n);
else if (numberSplit[0] == "0")
numbers.push(n);
continue;
}
}
// includes -
if (checkSegment.indexOf("-") > 0) {
// take both #
numberSplit = checkSegment.split("-");
if (numberSplit.length != 2) {
continue;
} else if (Number(numberSplit[0]) > Number(numberSplit[1])) {
continue;
} else {
n = numberSplit[0];
if (n && !(isNaN(n)))
numbers.push(n);
else if (numberSplit[0] == "0")
numbers.push(n);
n = numberSplit[1];
if (n && !(isNaN(n)))
numbers.push(n);
else if (numberSplit[1] == "0")
numbers.push(n);
continue;
}
}
}
// lastly, check that all the found numbers are in range
i = -1;
l = numbers.length;
if (l == 0)
return false;
while (++i < l) {
// alert(numbers[i]);
if (numbers[i] < range[0] || numbers[i] > range[1]) {
return false;
}
}
return true;
}
function cronValidate() {var cron = $("#cron").val(); var result = CronExpressionValidator.validateCronExpression(cron); if(result == true){ alert("格式正确"); } else{ alert("格式错误"); } return CronExpressionValidator.validateCronExpression(cron); } function CronExpressionValidator() { } CronExpressionValidator.validateCronExpression = function(value) {var results = true; if (value == null || value.length == 0) { returnfalse; } // split and test length var expressionArray = value.split(" "); var len = expressionArray.length; if ((len != 6) && (len != 7)) { returnfalse; } // check only one question mark var match = value.match(/\?/g); if (match != null && match.length > 1) { returnfalse; } // check only one question mark var dayOfTheMonthWildcard = ""; // if appropriate length test parts // [0] Seconds 0-59 , - * / if (CronExpressionValidator.isNotWildCard(expressionArray[0], /[\*]/gi)) { if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[0], [0, 59], "seconds")) { returnfalse; } } // [1] Minutes 0-59 , - * / if (CronExpressionValidator.isNotWildCard(expressionArray[1], /[\*]/gi)) { if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[1], [0, 59], "minutes")) { returnfalse; } } // [2] Hours 0-23 , - * / if (CronExpressionValidator.isNotWildCard(expressionArray[2], /[\*]/gi)) { if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[2], [0, 23], "hours")) { returnfalse; } } // [3] Day of month 1-31 , - * ? / L W C if (CronExpressionValidator.isNotWildCard(expressionArray[3], /[\*\?]/gi)) { if (!CronExpressionValidator.segmentValidator("([0-9LWC\\\\,-\\/])", expressionArray[3], [1, 31], "days of the month")) { returnfalse; } } else { dayOfTheMonthWildcard = expressionArray[3]; } // [4] Month 1-12 or JAN-DEC , - * / if (CronExpressionValidator.isNotWildCard(expressionArray[4], /[\*]/gi)) { expressionArray[4] = CronExpressionValidator.convertMonthsToInteger(expressionArray[4]); if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[4], [1, 12], "months")) { returnfalse; } } // [5] Day of week 1-7 or SUN-SAT , - * ? / L C # if (CronExpressionValidator.isNotWildCard(expressionArray[5], /[\*\?]/gi)) { expressionArray[5] = CronExpressionValidator.convertDaysToInteger(expressionArray[5]); if (!CronExpressionValidator.segmentValidator("([0-9LC#\\\\,-\\/])", expressionArray[5], [1, 7], "days of the week")) { returnfalse; } } else { if (dayOfTheMonthWildcard == String(expressionArray[5])) { returnfalse; } } // [6] Year empty or 1970-2099 , - * / if (len == 7) { if (CronExpressionValidator.isNotWildCard(expressionArray[6], /[\*]/gi)) { if (!CronExpressionValidator.segmentValidator("([0-9\\\\,-\\/])", expressionArray[6], [1970, 2099], "years")) { returnfalse; } } } returntrue; } // ---------------------------------- // isNotWildcard 静态方法; // ---------------------------------- CronExpressionValidator.isNotWildCard = function(value, expression) {var match = value.match(expression); return (match == null || match.length == 0) ? true : false; } // ---------------------------------- // convertDaysToInteger 静态方法; // ---------------------------------- CronExpressionValidator.convertDaysToInteger = function(value) {var v = value; v = v.replace(/SUN/gi, "1"); v = v.replace(/MON/gi, "2"); v = v.replace(/TUE/gi, "3"); v = v.replace(/WED/gi, "4"); v = v.replace(/THU/gi, "5"); v = v.replace(/FRI/gi, "6"); v = v.replace(/SAT/gi, "7"); return v; } // ---------------------------------- // convertMonthsToInteger 静态方法; // ---------------------------------- CronExpressionValidator.convertMonthsToInteger = function(value) {var v = value; v = v.replace(/JAN/gi, "1"); v = v.replace(/FEB/gi, "2"); v = v.replace(/MAR/gi, "3"); v = v.replace(/APR/gi, "4"); v = v.replace(/MAY/gi, "5"); v = v.replace(/JUN/gi, "6"); v = v.replace(/JUL/gi, "7"); v = v.replace(/AUG/gi, "8"); v = v.replace(/SEP/gi, "9"); v = v.replace(/OCT/gi, "10"); v = v.replace(/NOV/gi, "11"); v = v.replace(/DEC/gi, "12"); return v; } // ---------------------------------- // segmentValidator 静态方法; // ---------------------------------- CronExpressionValidator.segmentValidator = function(expression, value, range, segmentName) {var v = value; var numbers = newArray(); // first, check for any improper segments var reg = newRegExp(expression, "gi"); if (!reg.test(v)) { returnfalse; } // check duplicate types // check only one L var dupMatch = value.match(/L/gi); if (dupMatch != null && dupMatch.length > 1) { returnfalse; } // look through the segments // break up segments on ',' // check for special cases L,W,C,/,#,- var split = v.split(","); var i = -1; var l = split.length; var match; while (++i < l) { // set vars var checkSegment = split[i]; var n; var pattern = /(\w*)/; match = pattern.exec(checkSegment); // if just number pattern = /(\w*)\-?\d+(\w*)/; match = pattern.exec(checkSegment); if (match && match[0] == checkSegment && checkSegment.indexOf("L") == -1 && checkSegment.indexOf("l") == -1 && checkSegment.indexOf("C") == -1 && checkSegment.indexOf("c") == -1 && checkSegment.indexOf("W") == -1 && checkSegment.indexOf("w") == -1 && checkSegment.indexOf("/") == -1 && (checkSegment.indexOf("-") == -1 || checkSegment .indexOf("-") == 0) && checkSegment.indexOf("#") == -1) { n = match[0]; if (n && !(isNaN(n))) numbers.push(n); elseif (match[0] == "0") numbers.push(n); continue; } // includes L, C, or w pattern = /(\w*)L|C|W(\w*)/i; match = pattern.exec(checkSegment); if (match && match[0] != "" && (checkSegment.indexOf("L") > -1 || checkSegment.indexOf("l") > -1 || checkSegment.indexOf("C") > -1 || checkSegment.indexOf("c") > -1 || checkSegment.indexOf("W") > -1 || checkSegment .indexOf("w") > -1)) { // check just l or L if (checkSegment == "L" || checkSegment == "l") continue; pattern = /(\w*)\d+(l|c|w)?(\w*)/i; match = pattern.exec(checkSegment); // if something before or after if (!match || match[0] != checkSegment) { continue; } // get the number var numCheck = match[0]; numCheck = numCheck.replace(/(l|c|w)/ig, ""); n = Number(numCheck); if (n && !(isNaN(n))) numbers.push(n); elseif (match[0] == "0") numbers.push(n); continue; } var numberSplit; // includes / if (checkSegment.indexOf("/") > -1) { // take first # numberSplit = checkSegment.split("/"); if (numberSplit.length != 2) { continue; } else { n = numberSplit[0]; if (n && !(isNaN(n))) numbers.push(n); elseif (numberSplit[0] == "0") numbers.push(n); continue; } } // includes # if (checkSegment.indexOf("#") > -1) { // take first # numberSplit = checkSegment.split("#"); if (numberSplit.length != 2) { continue; } else { n = numberSplit[0]; if (n && !(isNaN(n))) numbers.push(n); elseif (numberSplit[0] == "0") numbers.push(n); continue; } } // includes - if (checkSegment.indexOf("-") > 0) { // take both # numberSplit = checkSegment.split("-"); if (numberSplit.length != 2) { continue; } elseif (Number(numberSplit[0]) > Number(numberSplit[1])) { continue; } else { n = numberSplit[0]; if (n && !(isNaN(n))) numbers.push(n); elseif (numberSplit[0] == "0") numbers.push(n); n = numberSplit[1]; if (n && !(isNaN(n))) numbers.push(n); elseif (numberSplit[1] == "0") numbers.push(n); continue; } } } // lastly, check that all the found numbers are in range i = -1; l = numbers.length; if (l == 0) returnfalse; while (++i < l) { // alert(numbers[i]); if (numbers[i] < range[0] || numbers[i] > range[1]) { returnfalse; } } returntrue; }
Javascript判断Crontab表达式是否合法的更多相关文章
- 六天玩转javascript:javascript变量与表达式(2)
本系列内容为本人平时项目实践和参照MDN,MSDN,<javascript语言精粹>,<Effective Javascript>等资料,并且整理自己EverNote的日常积累 ...
- 六天玩转javascript:javascript变量与表达式(1)
说明 本系列属于进阶系列,语常用语法等不在本系列介绍范围之内. 在我刚开始做一个程序员并开发项目的时候,我总是喜欢使用开发语言的各种特性,每次m$发布新版C#的时候我总是会把开发者预览版下好,亲自体验 ...
- JavaScript判断浏览器类型及版本
JavaScript是前端开发的主要语言,我们可以通过编写JavaScript程序来判断浏览器的类型及版本.JavaScript判断浏览器类型一般有两种办法,一种是根据各种浏览器独有的属性来分辨,另一 ...
- JavaScript权威指南--表达式与运算符
本章要点 表达式是javascript中的一个短语,javascript解释器会将其计算出一个结果. 程序中的常量.变量名就是一种简单的表达式.复杂的表达式是由简单的表达式组成的,比如数组访问表达式. ...
- Javascript判断数据类型的五种方式及其特殊性
Javascript判断数据类型的五种方式及区别 @ 目录 typeof instanceof Object.prototype.toString isArray iisNaN ----------- ...
- 《如何使用Javascript判断浏览器终端设备》
WEB开发中如何通过Javascript来判断终端为PC.IOS(iphone).Android呢? 可以通过判断浏览器的userAgent,用正则来判断手机是否是ios和Android客户端. va ...
- 菜鸟笔记:javascript基础之表达式和运算符
4.1 原始表达式 原始表达式是最简单的表达式~它不再包含其他表达式.它包含:直接量(程序中直接显示出来的数据值.)常量(程序中不会被修改的量)变量. 4.2 对象和数组的初始化表达式 对象和数组初始 ...
- JavaScript判断移动端及pc端访问不同的网站
JavaScript判断移动端及pc端访问不同的网站 现在很多网站都是分为两个版本,一个pc端的一个移动端的(响应式除外),针对这两个版本,就需要对访问的设备进行判断,如果是pc,就直接访问pc网站, ...
- 如何使用Javascript判断浏览器终端设备
WEB开发中如何通过Javascript来判断终端为PC.IOS(iphone).Android呢? 可以通过判断浏览器的userAgent,用正则来判断手机是否是ios和Android客户端 var ...
随机推荐
- Java NIO和IO的区别(转)
原文链接:Java NIO和IO的区别 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分的差异. 复制代码代码如下: IO NIO面向流 ...
- Swift:宏定义
一.简述 swift中并没有加入宏系统,C语言使用#define定义的基本常量在导入Swift时被Swift编译自动转为Swfit语言的全局变量.但复杂的宏定义不能被Swift转换.Swift中类似宏 ...
- DOS批处理中%cd%和%~dp0的异同分析
在DOS的批处理中,有时候需要知道当前的路径.在DOS中,有两个环境变量可以跟当前路径有关,一个是%cd%, 一个是%~dp0. 这两个变量的用法和代表的内容是不同的. 1. %cd% 可以用在批处理 ...
- 第二章 Base64与URLBase64
2.1.算法基本规则: 加密的算法公开 加密的密钥不公开 Base64算法公开.密钥也公开的特性不符合基本算法规则,所以很容易被破解,所以一般不用于企业级的加密操作. 注意:具体的算法与密钥(对于Ba ...
- 用EntityFramework6完成增删查改和事务【转】
http://www.cnblogs.com/wujingtao/p/5407821.html 上一节我们已经学习了如何使用EF连接数据库,并简单演示了一下如何使用EF6对数据库进行操作,这一节我来详 ...
- zTree怎么判断树有节点展开或者完全关闭的
树节点有个open属性,引用API: 记录 treeNode 节点的 展开 / 折叠 状态.1.初始化节点数据时,如果设定 treeNode.open = true,则会直接展开此节点2.叶子节点 t ...
- Python实现爬虫设置代理IP和伪装成浏览器的方法(转载)
https://www.jb51.net/article/139587.htm chrome_options = webdriver.ChromeOptions() chrome_options.ad ...
- 使用checkstyle来规范你的项目
Checkstyle是什么 自从做了程序员,关于格式化的讨论就不曾中断过,到底什么才是正确的,什么才是错误的,到现在也没有完整的定论.但随着时间发展,渐渐衍生出一套规范出来.没有什么绝对的正确和错误, ...
- ubuntu完全卸载apache2
最近刚接触ubuntu和apache,第一次配置就被apahce搞到完全崩溃,跟着网上的配置修改apache的charset和apache2.conf以后,开始出现访问http://localhost ...
- 如何实现json字符串和 BsonDocument的互相转换
String to BsonDocument string json = "{ 'foo' : 'bar' }"; MongoDB.Bson.BsonDocument docume ...