首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >正则表达式用于验证JSON

正则表达式用于验证JSON
EN

Stack Overflow用户
提问于 2010-04-06 16:17:13
回答 8查看 155.8K关注 0票数 97

我正在寻找一个允许我验证json的正则表达式。

我是Regex的新手,我知道使用Regex进行解析很糟糕,但是它可以用来验证吗?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-10-02 21:04:29

是的,完全的正则表达式验证是可能的。

大多数现代regex实现都允许使用递归regexpression,这可以验证完整的JSON序列化结构。json.org specification让这一切变得非常简单。

代码语言:javascript
复制
$pcre_regex = '
  /
  (?(DEFINE)
     (?<number>   -? (?= [1-9]|0(?!\d) ) \d+ (\.\d+)? ([eE] [+-]? \d+)? )    
     (?<boolean>   true | false | null )
     (?<string>    " ([^"\\\\]* | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]{4} )* " )
     (?<array>     \[  (?:  (?&json)  (?: , (?&json)  )*  )?  \s* \] )
     (?<pair>      \s* (?&string) \s* : (?&json)  )
     (?<object>    \{  (?:  (?&pair)  (?: , (?&pair)  )*  )?  \s* \} )
     (?<json>   \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) \s* )
  )
  \A (?&json) \Z
  /six   
';

它在PHP中和PCRE functions 一起工作得很好。不需要修改就可以在Perl中工作;当然也可以适用于其他语言。此外,它还成功地使用了JSON test cases

更简单的RFC4627验证

一种更简单的方法是RFC4627, section 6中指定的最小一致性检查。然而,它只是作为安全测试和基本的无效预防措施:

代码语言:javascript
复制
  var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
         text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
     eval('(' + text + ')');
票数 197
EN

Stack Overflow用户

发布于 2016-07-25 19:34:45

我尝试了@mario的答案,但它对我不起作用,因为我已经从JSON.org (archive)下载了测试套件,并且有4个失败的测试(fail1.json,fail18.json,fail25.json,fail27.json)。

我调查了错误,发现fail1.json实际上是正确的(根据手册的noteRFC-7159,有效字符串也是一个有效的JSON)。文件fail18.json也不是这样的,因为它实际上包含了正确的深度嵌套的JSON:

代码语言:javascript
复制
[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]

所以只剩下两个文件:fail25.jsonfail27.json

代码语言:javascript
复制
["  tab character   in  string  "]

代码语言:javascript
复制
["line
break"]

两者都包含无效字符。所以我像这样更新了模式(字符串子模式更新):

代码语言:javascript
复制
$pcreRegex = '/
          (?(DEFINE)
             (?<number>   -? (?= [1-9]|0(?!\d) ) \d+ (\.\d+)? ([eE] [+-]? \d+)? )
             (?<boolean>   true | false | null )
             (?<string>    " ([^"\n\r\t\\\\]* | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]{4} )* " )
             (?<array>     \[  (?:  (?&json)  (?: , (?&json)  )*  )?  \s* \] )
             (?<pair>      \s* (?&string) \s* : (?&json)  )
             (?<object>    \{  (?:  (?&pair)  (?: , (?&pair)  )*  )?  \s* \} )
             (?<json>   \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) \s* )
          )
          \A (?&json) \Z
          /six';

所以现在所有来自json.org的合法测试都可以通过了。

票数 12
EN

Stack Overflow用户

发布于 2012-05-24 04:20:25

我创建了一个Mario解决方案的Ruby实现,它确实有效:

代码语言:javascript
复制
# 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
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2583472

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档