Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Created April 29, 2015 11:34
Show Gist options
  • Save WebReflection/9f9d771f0d1f2579386a to your computer and use it in GitHub Desktop.
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`
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));
@WebReflection
Copy link
Author

performance is indeed brap anyway ... http://jsperf.com/json-isjson

if (!JSON.isJSON) JSON.isJSON = function isJSON(s) {
  try {
    JSON.parse(s);
    return true;
  } catch(e) {
    return false;
  }
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment