【问题标题】:How to parse "dd-MMM-yyyy" or "MMM-dd-yyyy" date string using single regular expression? [duplicate]如何使用单个正则表达式解析“dd-MMM-yyyy”或“MMM-dd-yyyy”日期字符串? [复制]
【发布时间】:2014-02-13 09:17:07
【问题描述】:

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

【问题讨论】:

  • @wared:我假设它是janfebmar 等,可能是大写的
  • 例如“2012 年 2 月 12 日”或“2012 年 2 月 12 日”
  • 尝试拆分 dd-MMM-yyyy 然后在索引 0 处你 ve 对 dd 在索引 1 u ve mmm 和索引 2 处你 ve yyyy
  • @MuhammadHisham 请不要在这里使用短信俚语。请注意,您的评论不能回答问题:stackoverflow.com/questions/21749728/…
  • @People :已将此问题标记为重复的人,必须知道其他重复的问题应该可以解决我的问题。你们提到的链接根本没有解决我的问题,因为这个问题本身与通过指定特定日期格式来解析日期不同。

标签: javascript regex date


【解决方案1】:

我会先颠倒月份和日期的位置,然后才能得到所有日期的相同格式:

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...

欢迎询问详情。

【讨论】:

  • 我想知道这个“自动关闭”是否没有失败... :-|
【解决方案2】:

是的,这当然是可能的,但您必须检查匹配的捕获组:

/^(?:(\d\d)-([a-z]{3})-(\d{4})|([a-z]{3})-(\d\d)-(\d{4}))$/i

如果组13 在匹配后定义,则使用dd-MMM-yyyy,如果定义组46,则使用另一个。

这个正则表达式不做任何合理性检查,所以它也会匹配99-XXX-9999,但这是一个不同的问题。

【讨论】:

  • 可行吗?当然。你应该这样做吗?绝对不是……
【解决方案3】:

首先可以将dd-MMM-yyyyMMM-dd-yyyy格式转换为dd-MMM-yyyy

通过使用:.replace(/([a-zA-Z]{3})-(\d{2})-(\d{4})/,"$2-$1-$3");

然后你可以使用正则表达式:/(\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

DEMO

【讨论】:

  • 我想使用单个正则表达式来解析这两种格式,而不是任何特定的格式。
  • @Prateek :编辑了我的答案。
【解决方案4】:

此变体添加了对称 YYY-mmm-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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多