How to parse “dd-MMM-yyyy” or “MMM-dd-yyyy” date string using single regular expression?
我正在获取日期字符串,如
我会先反转月和日的位置,得到所有日期的相同格式:
1 2 3 4 5 6 7 8 9 10 11 12 | 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]; |
1 2 3 4 | ^ beginning of the input (\w+) a word character, one or more times ($1) - a dash (\d+) a digit, one or more times ($2) |
。更进一步
既然您知道了如何分割输入,那么我希望通过将结果转换为日期对象来进一步了解这一点。首先,让我们打开chrome的控制台,快速检查输入是否可以按原样进行解析:
1 2 | new Date('12-Feb-2012') // Sun Feb 12 2012... new Date('Feb-12-2012') // Sun Feb 12 2012... |
很明显,Chrome可以很好地完成这项工作。这很好,但是其他实现不一定以相同的方式运行,您应该更好地依赖于规范。幸运的是,有人已经为您检查了它们:未记录的支持日期。分析格式?
概括地说,解析您自己的格式的能力可能因实现而异。只有一种可靠的格式,即
准确地说,预计
1 2 3 4 5 6 | 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"] |
。
还不错,工作就快完成了。实际上,正如在规范中提到的,解析器接受日期格式,如
1 2 | parts = parts.reverse(); // ["2012","02","12"] parts = parts.join('-'); //"2012-02-12" |
。
让我们看看控制台上的内容:
1 | new Date(parts) // Sun Feb 12 2012... |
完成!
结案或者,您可以这样做:
1 2 3 | 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]); |
。
通过将进程隐藏到函数中,您可以更进一步:
1 2 3 4 5 6 7 8 9 10 | 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); }; |
用法示例:
1 2 | var date = parseDate('12-Feb-2012'); // Sun Feb 12 2012... var date = parseDate('Feb-12-2012'); // Sun Feb 12 2012... |
。
请随时询问详情。
是的,这当然是可能的,但是您必须检查哪些捕获组匹配:
1 | /^(?:(\d\d)-([a-z]{3})-(\d{4})|([a-z]{3})-(\d\d)-(\d{4}))$/i |
如果匹配后定义了从
这个regex不做任何合理性检查,因此它也将匹配
首先,您可以将
使用:
然后可以使用regex:
代码:
1 2 3 4 5 6 | 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 |
号
演示
此变体添加了符号YYY MMM DD,允许使用单个数字的日数,并为语言独立性提供了月份名称的规范。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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")); |
号
显示器
1 2 3 4 5 6 7 | ["13","feb","2014"] ["Feb","13","2014"] ["2014","FEB","13"] ["1","feb","2014"] ["Feb","1","2014"] ["2014","FEB","1"] "01-fev-678" |
号