我收到日期字符串,如dd-MMM-yyyy
或MMM-dd-yyyy
格式。我想要的是使用一个正则表达式(不使用任何第三方插件)提取day
,month
和year
。有可能吗?
答案 0 :(得分:7)
我会先反转月份和日期的位置,确保所有日期都采用相同的格式:
function splitDate(input) {
return input.replace(
/^(\w+)-(\d+)/, '$2-$1'
).split('-');
}
var parts = splitDate('Feb-12-2012'); // ["12", "Feb", "2012"]
var parts = splitDate('12-Feb-2012'); // ["12", "Feb", "2012"]
var day = parts[0];
var month = parts[1];
var year = parts[2];
/^(\w+)-(\d+)/
仅匹配“Mmm-dd-yyyy”:
^ beginning of the input
(\w+) a word character, one or more times ($1)
- a dash
(\d+) a digit, one or more times ($2)
既然你知道如何分割输入,我想进一步将结果转换为Date对象。首先,让我们打开Chrome控制台,快速检查输入是否可解析:
new Date('12-Feb-2012') // Sun Feb 12 2012...
new Date('Feb-12-2012') // Sun Feb 12 2012...
显然,Chrome可以正常完成这项工作。这很好,但其他实现不一定表现相同,您应该更好地依赖于规范。幸运的是,有人已经为你检查了它们:undocumented supported Date.parse format?
总而言之,解析自己的格式的能力可能因实现而异。只有一种可靠的格式,即YYYY-MM-DDTHH:mm:ss.sssZ
,其中每个字母 - 除了“T”和“Z” - 代表一个数字。
准确地说,MM
应该是一个数字。如果要确保正确解析输入,则必须找到将月份部分转换为数字的方法。我们试试吧:
var months = {
Jan: '01', Feb: '02', Mar: '03', Apr: '04', May: '05', Jun: '06',
Jul: '07', Aug: '08', Sep: '09', Oct: '10', Nov: '11', Dec: '12'
};
var parts = splitDate('Feb-12-2012'); // ["12", "Feb", "2012"]
parts[1] = months[parts[1]]; // parts -> ["12", "02", "2012"]
没那么糟糕,工作差不多完成了。实际上,如规范中所提到的,解析器只接受YYYY-MM-DD
这样的日期格式,这很容易实现:
parts = parts.reverse(); // ["2012", "02", "12"]
parts = parts.join('-'); // "2012-02-12"
让我们看一下控制台的内容:
new Date(parts) // Sun Feb 12 2012...
完成!
或者,你可以这样做:
var parts = splitDate('Feb-12-2012'); // ["12", "Feb", "2012"]
parts[1] = months[parts[1]]; // parts -> ["12", "02", "2012"]
var date = new Date(parts[2], parts[1] - 1, parts[0]);
您可以通过将进程隐藏到函数中来进一步:
function parseDate(input) {
var map = {
Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5,
Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11
};
return (parseDate = function (input) {
input = input.replace(/^(\w+)-(\d+)/, '$2-$1').split('-');
return new Date(input[2], map[input[1]], input[0]);
})(input);
};
用法示例:
var date = parseDate('12-Feb-2012'); // Sun Feb 12 2012...
var date = parseDate('Feb-12-2012'); // Sun Feb 12 2012...
随时询问详情。
答案 1 :(得分:2)
是的,这当然是可能的,但您必须检查匹配的捕获组:
/^(?:(\d\d)-([a-z]{3})-(\d{4})|([a-z]{3})-(\d\d)-(\d{4}))$/i
如果在匹配后定义了群组1
到3
,则会使用dd-MMM-yyyy
,如果定义了群组4
到6
,那么另一个用了。
此正则表达式不会进行任何合理性检查,因此它也会匹配99-XXX-9999
,但这是一个不同的问题。
答案 2 :(得分:0)
首先,您可以将dd-MMM-yyyy
或MMM-dd-yyyy
格式转换为dd-MMM-yyyy
。
使用:.replace(/([a-zA-Z]{3})-(\d{2})-(\d{4})/,"$2-$1-$3");
然后你可以使用REGEX:/(\d+)-([a-zA-Z]{3})-(\d{4})/
代码:
var d="DEC-16-1990";
d=d.replace(/([a-zA-Z]{3})-(\d{2})-(\d{4})/,"$2-$1-$3");
var ar=d.match(/(\d+)-([a-zA-Z]{3})-(\d{4})/);
var day=ar[1]; //16
var month=ar[2]; //DEC
var year=ar[3]; //1990
答案 3 :(得分:-1)
此变体添加对称YYYY-mm-dd,允许单个数字日期数字,并提供月份名称的语言独立性规范。
function parseDate (date, months) {
var dateRE = /^(?:(\d\d?)-(%m)-(\d{4})|(%m)-(\d\d?)-(\d{4})|(\d{4})-(%m)-(\d\d?))$/;
if (!months)
months = 'jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec';
dateRE = RegExp (('' + dateRE).replace (/%m/g, months).slice (1, -1), 'i');
date = date.match (dateRE) || [date];
return date.length == 1 ?
date[0] : // Return string if parse error
[date[1] || date[4] || date[7], date[2] || date[5] || date[8], date[3] || date[6]|| date[9]];
}
console.log (parseDate ("13-feb-2014"));
console.log (parseDate ("Feb-13-2014"));
console.log (parseDate ("2014-FEB-13"));
console.log (parseDate ("1-feb-2014"));
console.log (parseDate ("Feb-1-2014"));
console.log (parseDate ("2014-FEB-1"));
console.log (parseDate ("01-fev-678"));
显示
["13", "feb", "2014"]
["Feb", "13", "2014"]
["2014", "FEB", "13"]
["1", "feb", "2014"]
["Feb", "1", "2014"]
["2014", "FEB", "1"]
"01-fev-678"