public
Last active

Apparently this is an actual JSON validator, written in late-model Regexp, using the Ruby interpreter.

  • Download Gist
is_json.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
# encoding: utf-8
 
module Constants
JSON_VALIDATOR_RE = /(
# define subtypes and build up the json syntax, BNF-grammar-style
# The {0} is a hack to simply define them as named groups here but not match on them yet
# I added some atomic grouping to prevent catastrophic backtracking on invalid inputs
(?<number> -?(?=[1-9]|0(?!\d))\d+(\.\d+)?([eE][+-]?\d+)?){0}
(?<boolean> true | false | null ){0}
(?<string> " (?>[^"\\\\]* | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]{4} )* " ){0}
(?<array> \[ (?> \g<json> (?: , \g<json> )* )? \s* \] ){0}
(?<pair> \s* \g<string> \s* : \g<json> ){0}
(?<object> \{ (?> \g<pair> (?: , \g<pair> )* )? \s* \} ){0}
(?<json> \s* (?> \g<number> | \g<boolean> | \g<string> | \g<array> | \g<object> ) \s* ){0}
)
\A \g<json> \Z
/uix
end
 
########## inline test running
if __FILE__==$PROGRAM_NAME
 
# support
class String
def unindent
gsub(/^#{scan(/^(?!\n)\s*/).min_by{|l|l.length}}/u, "")
end
end
 
require 'test/unit' unless defined? Test::Unit
class JsonValidationTest < Test::Unit::TestCase
include Constants
 
def setup
 
end
 
def test_json_validator_simple_string
assert_not_nil %s[ {"somedata": 5 }].match(JSON_VALIDATOR_RE)
end
 
def test_json_validator_deep_string
long_json = <<-JSON.unindent
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"id": 1918723,
"boolean": true,
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
JSON
 
assert_not_nil long_json.match(JSON_VALIDATOR_RE)
end
 
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.