Created
April 29, 2015 11:34
-
-
Save WebReflection/9f9d771f0d1f2579386a to your computer and use it in GitHub Desktop.
A probably pointless attempt to have an `isJSON` method without using `try/catch`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (!JSON.isJSON) JSON.isJSON = (function (RegExp) { | |
/*! (C) Andrea Giammarchi - MIT Style License */ | |
var | |
reStart = '^', | |
reEnd = '$', | |
valArrayEnd = '(,|\\])', | |
valObjectEnd = '(,|\\})', | |
asBoolean = '(true|false)', | |
asNull = '(null)', | |
asNumber = '(-?(?:[1-9]\\d*|0)(?:\\.\\d+)?(?:[eE][+-]\\d+)?)', | |
asString = '("(?:(?=(\\\\?))\\2.)*?")', | |
reBoolean = RegExp(reStart + asBoolean + reEnd), | |
reNull = RegExp(reStart + asNull + reEnd), | |
reNumber = RegExp(reStart + asNumber + reEnd), | |
reString = RegExp(reStart + asString + reEnd), | |
valArrayBoolean = RegExp(reStart + asBoolean + valArrayEnd), | |
valArrayNull = RegExp(reStart + asNull + valArrayEnd), | |
valArrayNumber = RegExp(reStart + asNumber + valArrayEnd), | |
valArrayString = RegExp(reStart + asString + valArrayEnd), | |
valObjectBoolean = RegExp(reStart + asBoolean + valObjectEnd), | |
valObjectNull = RegExp(reStart + asNull + valObjectEnd), | |
valObjectNumber = RegExp(reStart + asNumber + valObjectEnd), | |
valObjectString = RegExp(reStart + asString + valObjectEnd), | |
valObjectKey = RegExp(reStart + asString + ':') | |
; | |
function isNestedArray(str) { | |
var length = str.length, i = 1; | |
if (str.charAt(0) !== '[') return -1; | |
while (i < length) { | |
if (str.charAt(i) === ']') return str.charAt(i - 1) === ',' ? -1 : i + 1; | |
i = moveOn(str, i, valArrayBoolean, valArrayNull, valArrayNumber, valArrayString); | |
if (i < 0) return i; | |
} | |
return -1; | |
} | |
function isNestedObject(str) { | |
var length = str.length, i = 1; | |
if (str.charAt(0) !== '{') return -1; | |
while (i < length) { | |
if (str.charAt(i) === '}') return str.charAt(i - 1) === ',' ? -1 : i + 1; | |
if (!valObjectKey.test(str.slice(i))) return -1; | |
i += RegExp.$1.length + 1; | |
i = moveOn(str, i, valObjectBoolean, valObjectNull, valObjectNumber, valObjectString); | |
if (i < 0) return i; | |
} | |
return -1; | |
} | |
function isJSON(str) { | |
if (typeof str === 'string') { | |
switch (str.charAt(0)) { | |
case '[': return isNestedArray(str) === str.length; | |
case '{': return isNestedObject(str) === str.length; | |
case '"': return reString.test(str); | |
case 't': | |
case 'f': return reBoolean.test(str); | |
case 'n': return reNull.test(str); | |
default: return reNumber.test(str); | |
} | |
} | |
return false; | |
} | |
function moveOn(str, i, valBoolean, valNull, valNumber, valString) { | |
var p, s = str.slice(i); | |
switch (str.charAt(i)) { | |
case '[': | |
p = isNestedArray(s); | |
if (p < 0) return -1; | |
i += p; | |
if (str.charAt(i) === ',') i++; | |
break; | |
case '{': | |
p = isNestedObject(s); | |
if (p < 0) return -1; | |
i += p; | |
if (str.charAt(i) === ',') i++; | |
break; | |
case '"': | |
if (valString.test(s)) { | |
i += RegExp.$1.length; | |
if (RegExp.$3 === ',') i++; | |
break; | |
} else return -1; | |
case 't': | |
case 'f': | |
case 'n': | |
if ( | |
valBoolean.test(s) || | |
valNull.test(s) | |
) { | |
i += RegExp.$1.length; | |
if (RegExp.$2 === ',') i++; | |
break; | |
} else return -1; | |
default: | |
if (valNumber.test(s)) { | |
i += RegExp.$1.length; | |
if (RegExp.$2 === ',') i++; | |
break; | |
} else return -1; | |
} | |
return i; | |
} | |
return isJSON; | |
}(RegExp)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
performance is indeed brap anyway ... http://jsperf.com/json-isjson