Javascript regex not working in IE 6-9: "Function expected" error
I have the following code:
function parseDate(s) {
var date = new Date(s);
if (!isValidDate(date)) {
//iso 860 date parser, as some browsers do not support this via new Date yet
var re=/(\d\d\d\d)\D?(\d\d)\D?(\d\d)\D?(\d\d)\D?(\d\d\D?(\d\d\.?(\d*))?)(Z|[+-]\d\d?(:\d\d)?)?/;
var a=re(s).slice(1).map(function(x,i){
if (i==6 && x) x=parseInt(x,10)/Math.pow(10,x.length)*1000; // convert to milliseconds
return parseInt(x,10)||0;
});
date = new Date(Date.UTC(a[0],a[1]-1,a[2],a[3]-(a[7]||0),a[4],a[5],a[6]));
}
return date;
};
function isValidDate(d) {
if ( Object.prototype.toString.call(d) !== "[object Date]" )
return false;
return !isNaN(d.getTime());
}
This works in all browsers but IE6-9. There I get the error:
SCRIPT5002: Function expected
And it points to this line:
var a=re(s).slice(1).map(function(x,i){
Anyone know what is wrong with that and how to fix it?
Thanks, Wesley
Edit:
if I change the code to this:
function parseDate(s) {
var date = new Date(s);
if (!isValidDate(date)) {
//iso 860 date parser, as some browsers do not support this via new Date yet
var re=/(\d\d\d\d)\D?(\d\d)\D?(\d\d)\D?(\d\d)\D?(\d\d\D?(\d\d\.?(\d*))?)(Z|[+-]\d\d?(:\d\d)?)?/;
var a = re.exec(s);
if (a) {
a = a.slice(1);
a.map(function(x,i){
if (i==6 &&开发者_运维百科amp; x) x=parseInt(x,10)/Math.pow(10,x.length)*1000; // convert to milliseconds
return parseInt(x,10)||0;
});
document.getElementById('test1').innerHTML = (a[0] + ' ' + a[1] + ' ' + a[2] + ' ' + a[3] + ' ' + a[4] + ' ' + a[5] + ' ' + a[6] + ' ' + a[7]);
date = new Date(Date.UTC(a[0],a[1]-1,a[2],a[3]-(a[7]||0),a[4],a[5],a[6]));
}
}
return date;
};
It still doesn't work (complains about .map in IE) but interestingly also doesn't work in safari (and perhaps other browsers). Any reason why?
You'll note that the output (document.write from the new function is:
2008 11 01 20 39:57.78 57.78 78 -06:00
From the old function:
2008 11 1 20 39 57 780 -6
According to regular-expressions.info, you should be using re.exec(s)
rather than re(s)
. The page also mentions re.test(s)
, but that just returns true or false, re.exec(s)
actually returns the matches, which appears to be what you want.
Regarding .map
The .map()
array method is one of the new additions provided by ECMAScript 5; the latest official version of JavaScript (5.0 as December 2009 and now 5.1 as of June 2011). Few (if any) browsers fully support version 5 yet (and certainly not IE6). You can bet that it will be a while before you can rely on browsers to support all the new functionalities (such as Array.map()
).
Regarding the Date regex
Unfortunately JavaScript does not allow regexes to be specified using free-spacing mode. This makes longish regexes such as this one difficult to read. To shed some light on the reason why your algorithm isn't working, I've added comments to your regex, which indicate what the capture groups are really capturing. Here it is in PHP syntax:
$re_iso8601_date_needs_work = '%# Original Date regex
(\d\d\d\d)\D? # $1: Year.
(\d\d)\D? # $2: Month.
(\d\d)\D? # $3: Day.
(\d\d)\D? # $4: Hour.
( # $5: Minute and second. ???
\d\d\D? # Minute.
( # $6: Optional second.
\d\d\.? # Second (whole portion).
(\d*) # $7: Second (fractional portion).
)? # Second is optional.
) # End $5: minute and second.
( # $8: Optional timezone alternatives.
Z # Either UTC/Zulu.
| [+-]\d\d? # Or offset from UTC. Hours and
(:\d\d)? # $9: optional minutes.
)? # Timezone is optional.%x';
Hint: The fractional seconds are in $7
not $6
. And why are you capturing both minutes and seconds in group $5
?
Hope this helps! :)
精彩评论