在正则表达式中,是否可以准确地提取json标量值?

时间:2012-06-15 08:50:24

标签: regex json

希望从json中提取标量值。

  • 知道JSON使用双引号。

  • 知道标量的数据类型:字符串,数字,日期,布尔值。

  • 知道标量将位于第一级,即不是嵌入对象的属性

    {“want”:“string”} => “字符串”

    {“want”:123} => 123

    {“not”:{“want”:“wrong”},“want”:“right”} => “右

    {“nothing”:0} => null / not found

不知道如何处理打开/关闭引号,也不知道如何处理嵌入对象。

这可能吗?


这是迄今为止我提出的最好的方法:

// match `want` attribute
(?:"want"\s*:\s*)                                        

// string, number, boolean or null
(((?:")([^"]*)(?:"))|([-0-9][.eE0-9]*)|true|false|null)

// followed by comma or right bracket
(?:\s*(,|}))

这很好,因为它

  • 可以在postgres

  • 中投放
  • 抓取字符串

  • 抓取数字

  • 抓取boolean和null

这很糟糕,因为它

  • 不确保want是第一级属性

  • 字符串值不能有引号(“)在

1 个答案:

答案 0 :(得分:1)

这个表达式可以让你获得50%的胜利:

(?<=:\s*)(".*?"(?<!\\")|\-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?)(?=\s*})

或者,当写成多行正则表达式时:

(?x:
    (?<=:\s*)           # After : + space
    (

        ".*?"(?<!\\")   # String in double quotes

        |               # -or-

        \-?             # Optional leading -ve
        (0|[1-9]\d*)    # Number
        (\.\d+)?        # Optional fraction
        ([eE][+-]?\d+)? # Optional exponent

    )
    (?=\s*})            # space + }
)

这与您的嵌套对象示例({ "not": { "want" ...)不匹配,或者更确切地说,它将匹配,但错误的是。此外,您的最后一个示例({ "nothing": 0 } => null / not found)很难,因为0是有效数字。要解决此问题,我只需检查过程代码中的结果,并将0的结果替换为null

嵌套对象问题是一个完全不同的球类游戏。它正在进入词法分析领域而不是简单的标记化。那时,您可能只是使用JSON库,因为您无论如何都要编写完整的JSON解析器。幸运的是,JSON是一个非常简单的语法,使用第三方库并不昂贵 - 当然不过是自己动手。

我认为简短的回答是:来自一个简单的{ "name" : <value> }对象,是的,但是来自任何更复杂的,没有。

有关JSON语法的信息,请参阅http://www.json.org/