语法字符驱动,状态判断、维护。参考leetcode isValidNum
def isValidJson(json):
stack, inWord, inKey, inQuote, empty, metaChars, pair = [], False, False, False, True, '[]{},: \t', {'}': '{', ']': '['}
for c in json:
if inQuote:
if c == '"': inQuote = False
elif c == '"':
inQuote, inWord, empty = True, True, False
elif c not in metaChars: inWord, empty = True, False
elif c == ',':
if not inWord or inKey: return False
inWord = False
if stack[-1] == '{': inKey = True
elif c == ':':
if not inWord: return False
inKey, inWord = False, False
elif c in '{[':
stack.append(c)
inWord, empty = False, True
if c == '{': inKey = True
elif c in ']}':
if len(stack) == 0 or stack[-1] != pair[c]: return False
if not inWord and not empty: return False
if c == '}' and inKey and not empty: return False
stack.pop()
return len(stack) == 0
方法二: 基于上下文无关文法的 RD算法
P -> [(L | e)] | {( D | e)}
L -> E (,L | e)
E -> str | P
D -> F (,D | e)
F -> str:(P | str)
class JsonValidator {
private:
string s;
int p;
enum TOKEN { LEFT_BRACKET, RIGHT_BRACKET, LEFT_BRACE, RIGHT_BRACE, COLON, COMMA, WORD };
bool term(TOKEN t) {
if (p == s.size()) return false;
string m = "[]{}:,";
if (t < m.size()) {
while (p < s.size() && s[p] == ' ') ++p;
return p < s.size() && s[p++] == m[t];
}
else {
for (int start = -1, end = -1; (start < 0 || end < 0) && p < s.size(); ++p) {
if (m.find(s[p]) != string::npos && start < 0) return false;
else if (isalnum(s[p])) {
if (start < 0) start = p;
if (p == s.size() - 1 || !isalnum(s[p + 1])) end = p;
}
}
return p < s.size();
}
}
bool resume(int i) {
p = i;
return true;
}
bool e() { return true; }
bool P() {
int save = p;
return resume(save) && term(LEFT_BRACKET) && L() && term(RIGHT_BRACKET)
|| resume(save) && term(LEFT_BRACKET) && e() && term(RIGHT_BRACKET)
|| resume(save) && term(LEFT_BRACE) && D() && term(RIGHT_BRACE)
|| resume(save) && term(LEFT_BRACE) && e() && term(RIGHT_BRACE);
}
bool L() {
int save = p;
return resume(save) && E() && term(COMMA) && L()
|| resume(save) && E() && e();
}
bool E() {
int save = p;
return resume(save) && term(WORD)
|| resume(save) && P();
}
bool D() {
int save = p;
return resume(save) && F() && term(COMMA) && D()
|| resume(save) && F() && e();
}
bool F() {
int save = p;
return resume(save) && term(WORD) && term(COLON) && term(WORD)
|| resume(save) && term(WORD) && term(COLON) && P();
}
public:
JsonValidator(string s) : s(s), p(0) { isValid = P() && p == s.size(); }
bool isValid;
};