如何使用单个正则表达式解析"dd-MMM-yyyy"或"MMM-dd-yyyy"日期字符串?

Pra*_*eek 1 javascript regex date

我得到日期字符串dd-MMM-yyyyMMM-dd-yyyy格式.所有我想要的是提取day,monthyear用一个正则表达式(不使用任何第三方插件).可能吗?

lea*_*eaf 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];
Run Code Online (Sandbox Code Playgroud)

/^(\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)
Run Code Online (Sandbox Code Playgroud)

走得更远

既然你知道如何拆分输入,我想进一步将结果转换为Date对象.首先,让我们打开Chrome的控制台,快速检查输入是否可解析:

new Date('12-Feb-2012') // Sun Feb 12 2012...
new Date('Feb-12-2012') // Sun Feb 12 2012...
Run Code Online (Sandbox Code Playgroud)

显然,Chrome可以正常完成这项工作.这很好,但其他实现不一定表现相同,您应该更好地依赖于规范.幸运的是,有人已经为你检查了它们:未记录的支持Date.parse格式?

总而言之,解析自己的格式的能力可能因实现而异.只有一种可靠的格式,即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"]
Run Code Online (Sandbox Code Playgroud)

没那么糟糕,工作差不多完成了.实际上,正如规范中所提到的,解析器只接受日期格式YYYY-MM-DD,这很容易实现:

parts = parts.reverse(); // ["2012", "02", "12"]
parts = parts.join('-'); // "2012-02-12"
Run Code Online (Sandbox Code Playgroud)

让我们看看控制台说的内容:

new Date(parts) // Sun Feb 12 2012...
Run Code Online (Sandbox Code Playgroud)

完成!


关闭案件

或者,你可以这样做:

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]);
Run Code Online (Sandbox Code Playgroud)

您可以通过将进程隐藏到函数中来进一步:

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);
};
Run Code Online (Sandbox Code Playgroud)

用法示例:

var date = parseDate('12-Feb-2012'); // Sun Feb 12 2012...
var date = parseDate('Feb-12-2012'); // Sun Feb 12 2012...
Run Code Online (Sandbox Code Playgroud)

随意询问详情.